From 39c8885717bac02ce59a8276899d2d88db95706a Mon Sep 17 00:00:00 2001 From: Tyler Mairose Date: Wed, 13 Nov 2024 17:44:32 -0500 Subject: [PATCH 1/5] Stash files --- cmd/jsonpath/eval.go | 267 ++++++++++++++++++++++++++++++++++++-- go.mod | 1 + go.sum | 2 + internal/output/output.go | 13 ++ test.json | 73 +++++++++++ 5 files changed, 343 insertions(+), 13 deletions(-) create mode 100644 test.json diff --git a/cmd/jsonpath/eval.go b/cmd/jsonpath/eval.go index 74c2169c..473ab8de 100644 --- a/cmd/jsonpath/eval.go +++ b/cmd/jsonpath/eval.go @@ -6,11 +6,237 @@ import ( "os" "github.com/bhmj/jsonslice" + "github.com/charmbracelet/bubbles/help" + "github.com/charmbracelet/bubbles/key" + "github.com/charmbracelet/bubbles/textarea" + "github.com/charmbracelet/bubbles/textinput" + tea "github.com/charmbracelet/bubbletea" + "github.com/charmbracelet/lipgloss" "github.com/charmbracelet/log" "github.com/spf13/cobra" "github.com/tidwall/pretty" ) +const ( + initialInputs = 2 + maxInputs = 2 + minInputs = 1 + helpHeight = 5 +) + +var ( + cursorStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("212")) + + cursorLineStyle = lipgloss.NewStyle(). + Background(lipgloss.Color("57")). + Foreground(lipgloss.Color("230")) + + placeholderStyle = lipgloss.NewStyle(). + Foreground(lipgloss.Color("238")) + + endOfBufferStyle = lipgloss.NewStyle(). + Foreground(lipgloss.Color("235")) + + focusedPlaceholderStyle = lipgloss.NewStyle(). + Foreground(lipgloss.Color("99")) + + focusedBorderStyle = lipgloss.NewStyle(). + Border(lipgloss.RoundedBorder()). + BorderForeground(lipgloss.Color("238")) + + blurredBorderStyle = lipgloss.NewStyle(). + Border(lipgloss.NormalBorder(), false, true, false, false) +) + +type keymap = struct { + next, delete, quit key.Binding +} + +func newTextarea() textarea.Model { + t := textarea.New() + t.Prompt = "" + t.Placeholder = "Type something" + t.ShowLineNumbers = true + t.Cursor.Style = cursorStyle + t.FocusedStyle.Placeholder = focusedPlaceholderStyle + t.BlurredStyle.Placeholder = placeholderStyle + t.FocusedStyle.CursorLine = cursorLineStyle + t.FocusedStyle.Base = focusedBorderStyle + t.BlurredStyle.Base = blurredBorderStyle + t.FocusedStyle.EndOfBuffer = endOfBufferStyle + t.BlurredStyle.EndOfBuffer = endOfBufferStyle + t.KeyMap.DeleteWordBackward.SetEnabled(false) + t.KeyMap.LineNext = key.NewBinding(key.WithKeys("down")) + t.KeyMap.LinePrevious = key.NewBinding(key.WithKeys("up")) + t.Blur() + return t +} + +func newTextareaResults() textarea.Model { + t := textarea.New() + t.Prompt = "" + t.Placeholder = "Results" + t.ShowLineNumbers = false + t.Cursor.Style = cursorStyle + t.FocusedStyle.Placeholder = focusedPlaceholderStyle + t.BlurredStyle.Placeholder = placeholderStyle + t.FocusedStyle.CursorLine = cursorLineStyle + t.FocusedStyle.Base = focusedBorderStyle + t.FocusedStyle.EndOfBuffer = endOfBufferStyle + t.BlurredStyle.EndOfBuffer = endOfBufferStyle + t.KeyMap.DeleteWordBackward.SetEnabled(false) + t.KeyMap.LineNext = key.NewBinding(key.WithKeys("down")) + t.KeyMap.LinePrevious = key.NewBinding(key.WithKeys("up")) + t.Blur() + return t +} + +type editorModel struct { + textInput textinput.Model + width int + height int + keymap keymap + help help.Model + initialInput []byte + input textarea.Model + result textarea.Model +} + +func (m editorModel) Init() tea.Cmd { + return textarea.Blink +} + +func (m editorModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { + var cmds []tea.Cmd + + switch msg := msg.(type) { + case tea.KeyMsg: + switch { + case key.Matches(msg, m.keymap.quit): + m.textInput.Blur() + m.input.Blur() + m.result.Blur() + return m, tea.Quit + case key.Matches(msg, m.keymap.next): + if m.input.Focused() { + m.input.Blur() + m.textInput.Focus() + m.keymap.next.SetHelp("tab", "(switch to jsonpath query)") + } else { + m.input.Focus() + m.textInput.Blur() + m.keymap.next.SetHelp("tab", "(switch to editor)") + } + case key.Matches(msg, m.keymap.delete): + m.input.SetValue("") + } + + case tea.WindowSizeMsg: + m.height = msg.Height + m.width = msg.Width + } + + m.sizeInputs() + + var cmd tea.Cmd + + m.textInput, cmd = m.textInput.Update(msg) + cmds = append(cmds, cmd) + + m.input, cmd = m.input.Update(msg) + cmds = append(cmds, cmd) + + // Call jsonslice and evaluate path + + result, err := jsonslice.Get(m.initialInput, m.textInput.Value()) + + if err != nil { + m.result.SetValue(err.Error()) + } else { + m.result.SetValue(string(result)) + } + return m, tea.Batch(cmds...) +} + +func (m *editorModel) sizeInputs() { + m.input.SetWidth(m.width / 2) + m.input.SetHeight(m.height - helpHeight - 6) + + m.result.SetWidth(m.width / 2) + m.result.SetHeight(m.height - helpHeight - 6) +} + +func (m editorModel) View() string { + help := m.help.ShortHelpView([]key.Binding{ + m.keymap.next, + m.keymap.delete, + m.keymap.quit, + }) + + title := lipgloss.NewStyle().Width(40).MaxWidth(40).Height(2).MarginTop(1).Render("Enter jsonPath Query") + + input := lipgloss.NewStyle().Width(40).Height(2).Render(m.textInput.View()) + + leftAreaTitle := lipgloss.NewStyle().Bold(true).Height(1).Render("Input") + + rightAreaTitle := lipgloss.NewStyle().Bold(true).Height(1).Render("Results") + + left := lipgloss.NewStyle().Render(m.input.View()) + right := lipgloss.NewStyle().Render(m.result.View()) + + leftSection := lipgloss.JoinVertical(lipgloss.Left, leftAreaTitle, left) + rightSection := lipgloss.JoinVertical(lipgloss.Left, rightAreaTitle, right) + + splitStyle := lipgloss.NewStyle().Width(m.width / 2) + leftStyled := splitStyle.Render(leftSection) + rightStyled := splitStyle.Render(rightSection) + + textAreas := lipgloss.JoinHorizontal(lipgloss.Top, leftStyled, rightStyled) + + return lipgloss.JoinVertical(lipgloss.Left, title, input, textAreas, help) +} + +func newModel(defaultJson []byte) editorModel { + ti := textinput.New() + ti.Placeholder = "$.requestedItemsStatus[0].id" + ti.SetValue("$.requestedItemsStatus[0].id") + ti.Focus() + ti.CharLimit = 1000 + ti.Width = 500 + + m := editorModel{ + textInput: ti, + input: newTextarea(), + result: newTextareaResults(), + help: help.New(), + keymap: keymap{ + next: key.NewBinding( + key.WithKeys("tab"), + key.WithHelp("tab", "(switch to editor)"), + ), + delete: key.NewBinding( + key.WithKeys("shift+tab"), + key.WithHelp("shift+tab", "Clear editor"), + ), + quit: key.NewBinding( + key.WithKeys("esc", "ctrl+c"), + key.WithHelp("esc", "quit"), + ), + }, + } + + if defaultJson != nil { + m.initialInput = defaultJson + m.input.SetValue(string(defaultJson)) + m.textInput.SetValue("$") + } else { + m.input.SetValue("{\r \"accessRequestId\": \"2c91808b6ef1d43e016efba0ce470904\",\r \"requestedFor\": {\r \"type\": \"IDENTITY\",\r \"id\": \"2c91808568c529c60168cca6f90c1313\",\r \"name\": \"William Wilson\"\r },\r \"requestedItemsStatus\": [\r {\r \"id\": \"2c91808b6ef1d43e016efba0ce470904\",\r \"name\": \"Engineering Access\",\r \"description\": \"Access to engineering database\",\r \"type\": \"ACCESS_PROFILE\",\r \"operation\": \"Add\",\r \"comment\": \"William needs this access to do his job.\",\r \"clientMetadata\": {\r \"applicationName\": \"My application\"\r },\r \"approvalInfo\": [\r {\r \"approvalComment\": \"This access looks good. Approved.\",\r \"approvalDecision\": \"APPROVED\",\r \"approverName\": \"Stephen.Austin\",\r \"approver\": {\r \"type\": \"IDENTITY\",\r \"id\": \"2c91808568c529c60168cca6f90c1313\",\r \"name\": \"William Wilson\"\r }\r }\r ]\r }\r ],\r \"requestedBy\": {\r \"type\": \"IDENTITY\",\r \"id\": \"2c91808568c529c60168cca6f90c1313\",\r \"name\": \"William Wilson\"\r }\r}") + } + + m.textInput.Focus() + return m +} + func newEvalCommand() *cobra.Command { var filepath string var path string @@ -32,24 +258,39 @@ func newEvalCommand() *cobra.Command { if err != nil { return err } - } else { - log.Error("You must provide a file to preview") - } - result, err := jsonslice.Get(data, path) + if path != "" { + result, err := jsonslice.Get(data, path) - if err != nil { - return err - } + if err != nil { + return err + } + + // Format the JSON + formattedJSON := pretty.Pretty([]byte(result)) + + // Color the JSON + coloredJSON := pretty.Color(formattedJSON, nil) + + // Print formatted and colored JSON + fmt.Print(string(coloredJSON)) - // Format the JSON - formattedJSON := pretty.Pretty([]byte(result)) + } else { - // Color the JSON - coloredJSON := pretty.Color(formattedJSON, nil) + if _, err := tea.NewProgram(newModel(data), tea.WithAltScreen()).Run(); err != nil { + fmt.Println("Error while running program:", err) + log.Fatal(err) + } + } - // Print formatted and colored JSON - fmt.Print(string(coloredJSON)) + } else if filepath == "" && path != "" { + fmt.Println("You must provide a file to evaluate the path against") + } else { + if _, err := tea.NewProgram(newModel(nil), tea.WithAltScreen()).Run(); err != nil { + fmt.Println("Error while running program:", err) + log.Fatal(err) + } + } return nil diff --git a/go.mod b/go.mod index b30a6f6f..7e667ff9 100644 --- a/go.mod +++ b/go.mod @@ -22,6 +22,7 @@ require ( github.com/spf13/cobra v1.7.0 github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.18.1 + github.com/tidwall/pretty v1.2.1 github.com/vbauerster/mpb/v8 v8.6.1 github.com/zalando/go-keyring v0.2.3 golang.org/x/crypto v0.21.0 diff --git a/go.sum b/go.sum index fa5ce624..4af69087 100644 --- a/go.sum +++ b/go.sum @@ -166,6 +166,8 @@ github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcU github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= +github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= +github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/vbauerster/mpb/v8 v8.6.1 h1:XbBpIbJxJOO9yMcKPpI4oEFPW6tLAptefNQJNcGWri8= github.com/vbauerster/mpb/v8 v8.6.1/go.mod h1:S0tuIjikxlLxCeNijNhwAuD/BB3UE/d2nygG8SOldk0= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= diff --git a/internal/output/output.go b/internal/output/output.go index 03588141..c9a691d0 100644 --- a/internal/output/output.go +++ b/internal/output/output.go @@ -11,6 +11,7 @@ import ( "github.com/charmbracelet/log" "github.com/mrz1836/go-sanitize" "github.com/olekukonko/tablewriter" + "github.com/sailpoint-oss/sailpoint-cli/internal/util" ) func SaveJSONFile[T any](formattedResponse T, fileName string, folderPath string) error { @@ -100,3 +101,15 @@ func WriteTable(writer io.Writer, headers []string, entries [][]string, sortKey table.Render() } + +func WriteJson(jsonString []byte) string { + var err error + var data map[string]interface{} + + err = json.Unmarshal(jsonString, &data) + if err != nil { + log.Error(err) + } + + return util.RenderMarkdown("```json\n" + util.PrettyPrint(data) + "\n```") +} diff --git a/test.json b/test.json new file mode 100644 index 00000000..9174e21a --- /dev/null +++ b/test.json @@ -0,0 +1,73 @@ +{ + "objects": [ + { + "jwsHeader": null, + "jwsSignature": null, + "version": 1, + "self": { + "type": "SOURCE", + "id": "ac2887ffe0e7435a8c18c73f7ae94c7b", + "name": "TRAKK-WS" + }, + "object": { + "id": "ac2887ffe0e7435a8c18c73f7ae94c7b", + "name": "TRAKK-WS", + "type": "Web Services", + "connectorClass": "sailpoint.connector.webservices.WebServicesConnector", + "connectorScriptName": "web-services-angularsc", + "description": "Timecard System via REST API", + "deleteThreshold": 10, + "provisionAsCsv": false, + "owner": { + "type": "IDENTITY", + "id": "29b6ee3f91484d159b1ceac3109af151", + "name": "se.admin" + }, + "features": [ + "AUTHENTICATE", + "PROVISIONING", + "ENABLE", + "PASSWORD", + "UNLOCK" + ], + "schemas": [ + { + "nativeObjectType": "user", + "identityAttribute": "userId", + "displayAttribute": "username", + "hierarchyAttribute": null, + "includePermissions": false, + "features": [], + "configuration": {}, + "id": "58acc494b2e74485aa1d2203b22e7ba2", + "name": "account", + "created": "2023-06-01T21:47:45.281Z", + "modified": "2023-06-01T21:47:46.145Z" + }, + { + "nativeObjectType": "group", + "identityAttribute": "", + "displayAttribute": "", + "hierarchyAttribute": null, + "includePermissions": false, + "features": [], + "configuration": {}, + "attributes": [], + "id": "47aa9903904647298a22a43d0ed90552", + "name": "group", + "created": "2023-06-01T21:47:45.281Z", + "modified": "2023-06-01T21:47:46.150Z" + } + ], + "managementWorkgroup": null, + "passwordPolicies": [ + { + "type": "PASSWORD_POLICY", + "id": "2d808a98573c4e3582846945c46ee3f1", + "name": "Default Policy" + } + ] + } + } + ] +} From 232b7797ce9b8d014cdb50db330e741b55b96620 Mon Sep 17 00:00:00 2001 From: Tyler Mairose Date: Thu, 21 Nov 2024 17:26:50 -0500 Subject: [PATCH 2/5] Update command to include interactive json path editor --- cmd/jsonpath/eval.go | 42 +++++++++++++++++++++++++----------- go.mod | 22 ++++++++++--------- go.sum | 51 +++++++++++++++++++++++++++----------------- 3 files changed, 72 insertions(+), 43 deletions(-) diff --git a/cmd/jsonpath/eval.go b/cmd/jsonpath/eval.go index 473ab8de..6902116a 100644 --- a/cmd/jsonpath/eval.go +++ b/cmd/jsonpath/eval.go @@ -82,9 +82,11 @@ func newTextareaResults() textarea.Model { t.BlurredStyle.Placeholder = placeholderStyle t.FocusedStyle.CursorLine = cursorLineStyle t.FocusedStyle.Base = focusedBorderStyle + t.BlurredStyle.Base = blurredBorderStyle t.FocusedStyle.EndOfBuffer = endOfBufferStyle t.BlurredStyle.EndOfBuffer = endOfBufferStyle t.KeyMap.DeleteWordBackward.SetEnabled(false) + t.KeyMap.DeleteCharacterForward.SetEnabled(false) t.KeyMap.LineNext = key.NewBinding(key.WithKeys("down")) t.KeyMap.LinePrevious = key.NewBinding(key.WithKeys("up")) t.Blur() @@ -118,13 +120,20 @@ func (m editorModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { m.result.Blur() return m, tea.Quit case key.Matches(msg, m.keymap.next): - if m.input.Focused() { - m.input.Blur() - m.textInput.Focus() - m.keymap.next.SetHelp("tab", "(switch to jsonpath query)") - } else { + if m.textInput.Focused() { m.input.Focus() m.textInput.Blur() + m.result.Blur() + m.keymap.next.SetHelp("tab", "(switch to results)") + } else if m.input.Focused() { + m.input.Blur() + m.textInput.Blur() + m.result.Focus() + m.keymap.next.SetHelp("tab", "(switch to jsonPath query)") + } else if m.result.Focused() { + m.input.Blur() + m.result.Blur() + m.textInput.Focus() m.keymap.next.SetHelp("tab", "(switch to editor)") } case key.Matches(msg, m.keymap.delete): @@ -138,6 +147,17 @@ func (m editorModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { m.sizeInputs() + if !m.result.Focused() { + + result, err := jsonslice.Get(m.initialInput, m.textInput.Value()) + + if err != nil { + m.result.SetValue(err.Error()) + } else { + m.result.SetValue(string(result)) + } + } + var cmd tea.Cmd m.textInput, cmd = m.textInput.Update(msg) @@ -146,15 +166,11 @@ func (m editorModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { m.input, cmd = m.input.Update(msg) cmds = append(cmds, cmd) - // Call jsonslice and evaluate path + m.result, cmd = m.result.Update(msg) + cmds = append(cmds, cmd) - result, err := jsonslice.Get(m.initialInput, m.textInput.Value()) + // Call jsonslice and evaluate path - if err != nil { - m.result.SetValue(err.Error()) - } else { - m.result.SetValue(string(result)) - } return m, tea.Batch(cmds...) } @@ -199,9 +215,9 @@ func (m editorModel) View() string { func newModel(defaultJson []byte) editorModel { ti := textinput.New() ti.Placeholder = "$.requestedItemsStatus[0].id" + ti.CharLimit = 1000 ti.SetValue("$.requestedItemsStatus[0].id") ti.Focus() - ti.CharLimit = 1000 ti.Width = 500 m := editorModel{ diff --git a/go.mod b/go.mod index 7e667ff9..af082785 100644 --- a/go.mod +++ b/go.mod @@ -4,10 +4,10 @@ go 1.21 require ( github.com/bhmj/jsonslice v1.1.3 - github.com/charmbracelet/bubbles v0.16.1 - github.com/charmbracelet/bubbletea v0.24.2 + github.com/charmbracelet/bubbles v0.20.1-0.20241115133003-398e92c5ae72 + github.com/charmbracelet/bubbletea v1.1.2 github.com/charmbracelet/glamour v0.6.0 - github.com/charmbracelet/lipgloss v0.8.0 + github.com/charmbracelet/lipgloss v1.0.0 github.com/charmbracelet/log v0.2.4 github.com/fatih/color v1.15.0 github.com/golang/mock v1.6.0 @@ -48,9 +48,11 @@ require ( github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/aymerick/douceur v0.2.0 // indirect github.com/bhmj/xpression v0.9.1 // indirect - github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 // indirect + github.com/charmbracelet/x/ansi v0.4.2 // indirect + github.com/charmbracelet/x/term v0.2.0 // indirect github.com/danieljoos/wincred v1.2.0 // indirect github.com/dlclark/regexp2 v1.10.0 // indirect + github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/go-logfmt/logfmt v0.6.0 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect @@ -63,20 +65,20 @@ require ( github.com/lucasb-eyer/go-colorful v1.2.0 // 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/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-localereader v0.0.1 // indirect - github.com/mattn/go-runewidth v0.0.15 // indirect + github.com/mattn/go-runewidth v0.0.16 // indirect github.com/microcosm-cc/bluemonday v1.0.25 // indirect github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect github.com/muesli/cancelreader v0.2.2 // indirect github.com/muesli/reflow v0.3.0 // indirect github.com/muesli/termenv v0.15.2 // indirect github.com/pelletier/go-toml/v2 v2.1.1 // indirect - github.com/rivo/uniseg v0.4.4 // indirect + github.com/rivo/uniseg v0.4.7 // indirect github.com/rogpeppe/go-internal v1.11.0 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect - github.com/sahilm/fuzzy v0.1.0 // indirect + github.com/sahilm/fuzzy v0.1.1 // indirect github.com/sourcegraph/conc v0.3.0 // indirect github.com/spf13/afero v1.11.0 // indirect github.com/spf13/cast v1.6.0 // indirect @@ -85,8 +87,8 @@ require ( github.com/yuin/goldmark-emoji v1.0.2 // indirect go.uber.org/multierr v1.11.0 // indirect golang.org/x/net v0.23.0 // indirect - golang.org/x/sync v0.5.0 // indirect - golang.org/x/sys v0.18.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.26.0 // indirect golang.org/x/text v0.14.0 // indirect google.golang.org/appengine v1.6.8 // indirect google.golang.org/protobuf v1.31.0 // indirect diff --git a/go.sum b/go.sum index 4af69087..c2448f55 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,5 @@ +github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= +github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow= github.com/VividCortex/ewma v1.2.0/go.mod h1:nz4BbCtbLyFDeC9SUHbtcT5644juEuWfUAUnGx7j5l4= github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8= @@ -11,24 +13,30 @@ github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn github.com/aymanbagabas/go-osc52 v1.0.3/go.mod h1:zT8H+Rk4VSabYN90pWyugflM3ZhpTZNC7cASDfUCdT4= github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= +github.com/aymanbagabas/go-udiff v0.2.0 h1:TK0fH4MteXUDspT88n8CKzvK0X9O2xu9yQjWpi6yML8= +github.com/aymanbagabas/go-udiff v0.2.0/go.mod h1:RE4Ex0qsGkTAJoQdQQCA0uG+nAzJO/pI/QwceO5fgrA= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/bhmj/jsonslice v1.1.3 h1:aVYmtuQ8Gg1L3mAOFq3NMtfip8teUvC+DNArhv7IRDY= github.com/bhmj/jsonslice v1.1.3/go.mod h1:O3ZoA0zdEefdbk1dkU5aWPOA36zQhhS/HV6RQFLTlnU= github.com/bhmj/xpression v0.9.1 h1:N7bX/nWx9oFi/zsiMTx2ehoRApTDAWdQadq/5o2wMGk= github.com/bhmj/xpression v0.9.1/go.mod h1:j9oYmEXJjeL9mrgW1+ZDBKJXnbupsCPGhlO9J5YhS1Q= -github.com/charmbracelet/bubbles v0.16.1 h1:6uzpAAaT9ZqKssntbvZMlksWHruQLNxg49H5WdeuYSY= -github.com/charmbracelet/bubbles v0.16.1/go.mod h1:2QCp9LFlEsBQMvIYERr7Ww2H2bA7xen1idUDIzm/+Xc= -github.com/charmbracelet/bubbletea v0.24.2 h1:uaQIKx9Ai6Gdh5zpTbGiWpytMU+CfsPp06RaW2cx/SY= -github.com/charmbracelet/bubbletea v0.24.2/go.mod h1:XdrNrV4J8GiyshTtx3DNuYkR1FDaJmO3l2nejekbsgg= +github.com/charmbracelet/bubbles v0.20.1-0.20241115133003-398e92c5ae72 h1:oc5D9OAoKDZoXIDA8HpMThgLcW7CTfMZxTLM1gLMt0A= +github.com/charmbracelet/bubbles v0.20.1-0.20241115133003-398e92c5ae72/go.mod h1:1WuvnY5+/Kf/JMo0ispmMqILezqZMLBKac+4VANbhfs= +github.com/charmbracelet/bubbletea v1.1.2 h1:naQXF2laRxyLyil/i7fxdpiz1/k06IKquhm4vBfHsIc= +github.com/charmbracelet/bubbletea v1.1.2/go.mod h1:9HIU/hBV24qKjlehyj8z1r/tR9TYTQEag+cWZnuXo8E= github.com/charmbracelet/glamour v0.6.0 h1:wi8fse3Y7nfcabbbDuwolqTqMQPMnVPeZhDM273bISc= github.com/charmbracelet/glamour v0.6.0/go.mod h1:taqWV4swIMMbWALc0m7AfE9JkPSU8om2538k9ITBxOc= -github.com/charmbracelet/lipgloss v0.8.0 h1:IS00fk4XAHcf8uZKc3eHeMUTCxUH6NkaTrdyCQk84RU= -github.com/charmbracelet/lipgloss v0.8.0/go.mod h1:p4eYUZZJ/0oXTuCQKFF8mqyKCz0ja6y+7DniDDw5KKU= +github.com/charmbracelet/lipgloss v1.0.0 h1:O7VkGDvqEdGi93X+DeqsQ7PKHDgtQfF8j8/O2qFMQNg= +github.com/charmbracelet/lipgloss v1.0.0/go.mod h1:U5fy9Z+C38obMs+T+tJqst9VGzlOYGj4ri9reL3qUlo= github.com/charmbracelet/log v0.2.4 h1:3pKtq5/Y5QMKtcZt7kDqD1p9w7lICzHYQACBFY4ocHA= github.com/charmbracelet/log v0.2.4/go.mod h1:nQGK8tvc4pS9cvVEH/pWJiZ50eUq1aoXUOjGpXvdD0k= -github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 h1:q2hJAaP1k2wIvVRd/hEHD7lacgqrCPS+k8g1MndzfWY= -github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk= +github.com/charmbracelet/x/ansi v0.4.2 h1:0JM6Aj/g/KC154/gOP4vfxun0ff6itogDYk41kof+qk= +github.com/charmbracelet/x/ansi v0.4.2/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw= +github.com/charmbracelet/x/exp/golden v0.0.0-20241011142426-46044092ad91 h1:payRxjMjKgx2PaCWLZ4p3ro9y97+TVLZNaRZgJwSVDQ= +github.com/charmbracelet/x/exp/golden v0.0.0-20241011142426-46044092ad91/go.mod h1:wDlXFlCrmJ8J+swcL/MnGUuYnqgQdW9rhSD61oNMb6U= +github.com/charmbracelet/x/term v0.2.0 h1:cNB9Ot9q8I711MyZ7myUR5HFWL/lc3OpU8jZ4hwm0x0= +github.com/charmbracelet/x/term v0.2.0/go.mod h1:GVxgxAbjUrmpvIINHIQnJJKpMlHiZ4cktEQCN6GWyF0= 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/danieljoos/wincred v1.2.0 h1:ozqKHaLK0W/ii4KVbbvluM91W2H3Sh0BncbUNPS7jLE= @@ -40,6 +48,8 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8Yc github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= github.com/dlclark/regexp2 v1.10.0 h1:+/GIL799phkJqYW+3YbOd8LCcbHzT0Pbo8zl70MHsq0= github.com/dlclark/regexp2 v1.10.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= +github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4= +github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM= github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= @@ -89,15 +99,15 @@ github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3v 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/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4= github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= -github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= +github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/microcosm-cc/bluemonday v1.0.21/go.mod h1:ytNkv4RrDrLJ2pqlsSI46O6IVXmZOBBD4SaJyDwwTkM= github.com/microcosm-cc/bluemonday v1.0.25 h1:4NEwSfiJ+Wva0VxN5B8OwMicaJvD8r9tlJWm9rtloEg= github.com/microcosm-cc/bluemonday v1.0.25/go.mod h1:ZIOjCQp1OrzBBPIJmfX4qDYFuhU02nx4bn030ixfHLE= @@ -126,8 +136,8 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= -github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= +github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= @@ -136,8 +146,8 @@ github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6ke github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= -github.com/sahilm/fuzzy v0.1.0 h1:FzWGaw2Opqyu+794ZQ9SYifWv2EIXpwP4q8dY1kDAwI= -github.com/sahilm/fuzzy v0.1.0/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y= +github.com/sahilm/fuzzy v0.1.1 h1:ceu5RHF8DGgoi+/dR5PsECjCDH1BE3Fnmpo7aVXOdRA= +github.com/sahilm/fuzzy v0.1.1/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y= github.com/sailpoint-oss/golang-sdk/v2 v2.1.13 h1:tEWRYCdpQc+hVRKKd1bILXr5PwAu5JfJCOkncJLXsmI= github.com/sailpoint-oss/golang-sdk/v2 v2.1.13/go.mod h1:hZdRdJzkrEzdiiVqzblaCdYxGM9rKXMC0vhIom+WBpc= github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 h1:JIAuq3EEf9cgbU6AtGPK4CTG3Zf6CKMNqf0MHTggAUA= @@ -208,22 +218,23 @@ golang.org/x/oauth2 v0.15.0/go.mod h1:q48ptWNTY5XWf+JNten23lcvHpLJ0ZSxF5ttTHKVCA golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= -golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/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-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/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-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= +golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= From 7ebb61cee83dd37f02f16f599ddf89b2267b4411 Mon Sep 17 00:00:00 2001 From: Tyler Mairose Date: Thu, 21 Nov 2024 17:28:04 -0500 Subject: [PATCH 3/5] remove test file --- test.json | 73 ------------------------------------------------------- 1 file changed, 73 deletions(-) delete mode 100644 test.json diff --git a/test.json b/test.json deleted file mode 100644 index 9174e21a..00000000 --- a/test.json +++ /dev/null @@ -1,73 +0,0 @@ -{ - "objects": [ - { - "jwsHeader": null, - "jwsSignature": null, - "version": 1, - "self": { - "type": "SOURCE", - "id": "ac2887ffe0e7435a8c18c73f7ae94c7b", - "name": "TRAKK-WS" - }, - "object": { - "id": "ac2887ffe0e7435a8c18c73f7ae94c7b", - "name": "TRAKK-WS", - "type": "Web Services", - "connectorClass": "sailpoint.connector.webservices.WebServicesConnector", - "connectorScriptName": "web-services-angularsc", - "description": "Timecard System via REST API", - "deleteThreshold": 10, - "provisionAsCsv": false, - "owner": { - "type": "IDENTITY", - "id": "29b6ee3f91484d159b1ceac3109af151", - "name": "se.admin" - }, - "features": [ - "AUTHENTICATE", - "PROVISIONING", - "ENABLE", - "PASSWORD", - "UNLOCK" - ], - "schemas": [ - { - "nativeObjectType": "user", - "identityAttribute": "userId", - "displayAttribute": "username", - "hierarchyAttribute": null, - "includePermissions": false, - "features": [], - "configuration": {}, - "id": "58acc494b2e74485aa1d2203b22e7ba2", - "name": "account", - "created": "2023-06-01T21:47:45.281Z", - "modified": "2023-06-01T21:47:46.145Z" - }, - { - "nativeObjectType": "group", - "identityAttribute": "", - "displayAttribute": "", - "hierarchyAttribute": null, - "includePermissions": false, - "features": [], - "configuration": {}, - "attributes": [], - "id": "47aa9903904647298a22a43d0ed90552", - "name": "group", - "created": "2023-06-01T21:47:45.281Z", - "modified": "2023-06-01T21:47:46.150Z" - } - ], - "managementWorkgroup": null, - "passwordPolicies": [ - { - "type": "PASSWORD_POLICY", - "id": "2d808a98573c4e3582846945c46ee3f1", - "name": "Default Policy" - } - ] - } - } - ] -} From 79f365e85ff74b77f7ce0ef5ab10b0b569aa357f Mon Sep 17 00:00:00 2001 From: Tyler Mairose Date: Thu, 21 Nov 2024 17:35:46 -0500 Subject: [PATCH 4/5] remove added writeJSON function --- internal/output/output.go | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/internal/output/output.go b/internal/output/output.go index c9a691d0..03588141 100644 --- a/internal/output/output.go +++ b/internal/output/output.go @@ -11,7 +11,6 @@ import ( "github.com/charmbracelet/log" "github.com/mrz1836/go-sanitize" "github.com/olekukonko/tablewriter" - "github.com/sailpoint-oss/sailpoint-cli/internal/util" ) func SaveJSONFile[T any](formattedResponse T, fileName string, folderPath string) error { @@ -101,15 +100,3 @@ func WriteTable(writer io.Writer, headers []string, entries [][]string, sortKey table.Render() } - -func WriteJson(jsonString []byte) string { - var err error - var data map[string]interface{} - - err = json.Unmarshal(jsonString, &data) - if err != nil { - log.Error(err) - } - - return util.RenderMarkdown("```json\n" + util.PrettyPrint(data) + "\n```") -} From 93aff4c199f3438b0caf5fc04cb1970804d1110d Mon Sep 17 00:00:00 2001 From: Tyler Mairose Date: Mon, 25 Nov 2024 09:46:16 -0500 Subject: [PATCH 5/5] Use textarea input at all times to evaluate path --- cmd/jsonpath/eval.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cmd/jsonpath/eval.go b/cmd/jsonpath/eval.go index 6902116a..64389f20 100644 --- a/cmd/jsonpath/eval.go +++ b/cmd/jsonpath/eval.go @@ -148,8 +148,7 @@ func (m editorModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { m.sizeInputs() if !m.result.Focused() { - - result, err := jsonslice.Get(m.initialInput, m.textInput.Value()) + result, err := jsonslice.Get([]byte(m.input.Value()), m.textInput.Value()) if err != nil { m.result.SetValue(err.Error())