@@ -3,15 +3,18 @@ package checks
33import (
44 "bytes"
55 "encoding/json"
6+ "errors"
67 "fmt"
78 "io"
89 "net/http"
910 "os"
1011 "os/exec"
12+ "regexp"
1113 "strings"
1214 "time"
1315
1416 api "github.com/bootdotdev/bootdev/client"
17+ "github.com/itchyny/gojq"
1518 "github.com/spf13/cobra"
1619)
1720
@@ -143,3 +146,82 @@ func CLIChecks(cliData api.CLIData, submitBaseURL *string) (results []api.CLISte
143146 }
144147 return results
145148}
149+
150+ // truncateAndStringifyBody
151+ // in some lessons we yeet the entire body up to the server, but we really shouldn't ever care
152+ // about more than 100,000 stringified characters of it, so this protects against giant bodies
153+ func truncateAndStringifyBody (body []byte ) string {
154+ bodyString := string (body )
155+ const maxBodyLength = 1000000
156+ if len (bodyString ) > maxBodyLength {
157+ bodyString = bodyString [:maxBodyLength ]
158+ }
159+ return bodyString
160+ }
161+
162+ func parseVariables (body []byte , vardefs []api.HTTPRequestResponseVariable , variables map [string ]string ) error {
163+ for _ , vardef := range vardefs {
164+ val , err := valFromJQPath (vardef .Path , string (body ))
165+ if err != nil {
166+ return err
167+ }
168+ variables [vardef .Name ] = fmt .Sprintf ("%v" , val )
169+ }
170+ return nil
171+ }
172+
173+ func valFromJQPath (path string , jsn string ) (any , error ) {
174+ vals , err := valsFromJQPath (path , jsn )
175+ if err != nil {
176+ return nil , err
177+ }
178+ if len (vals ) != 1 {
179+ return nil , errors .New ("invalid number of values found" )
180+ }
181+ val := vals [0 ]
182+ if val == nil {
183+ return nil , errors .New ("value not found" )
184+ }
185+ return val , nil
186+ }
187+
188+ func valsFromJQPath (path string , jsn string ) ([]any , error ) {
189+ var parseable any
190+ err := json .Unmarshal ([]byte (jsn ), & parseable )
191+ if err != nil {
192+ return nil , err
193+ }
194+
195+ query , err := gojq .Parse (path )
196+ if err != nil {
197+ return nil , err
198+ }
199+ iter := query .Run (parseable )
200+ vals := []any {}
201+ for {
202+ v , ok := iter .Next ()
203+ if ! ok {
204+ break
205+ }
206+ if err , ok := v .(error ); ok {
207+ if err , ok := err .(* gojq.HaltError ); ok && err .Value () == nil {
208+ break
209+ }
210+ return nil , err
211+ }
212+ vals = append (vals , v )
213+ }
214+ return vals , nil
215+ }
216+
217+ func InterpolateVariables (template string , vars map [string ]string ) string {
218+ r := regexp .MustCompile (`\$\{([^}]+)\}` )
219+ return r .ReplaceAllStringFunc (template , func (m string ) string {
220+ // Extract the key from the match, which is in the form ${key}
221+ key := strings .TrimSuffix (strings .TrimPrefix (m , "${" ), "}" )
222+ if val , ok := vars [key ]; ok {
223+ return val
224+ }
225+ return m // return the original placeholder if no substitution found
226+ })
227+ }
0 commit comments