@@ -3,15 +3,18 @@ package checks
3
3
import (
4
4
"bytes"
5
5
"encoding/json"
6
+ "errors"
6
7
"fmt"
7
8
"io"
8
9
"net/http"
9
10
"os"
10
11
"os/exec"
12
+ "regexp"
11
13
"strings"
12
14
"time"
13
15
14
16
api "github.com/bootdotdev/bootdev/client"
17
+ "github.com/itchyny/gojq"
15
18
"github.com/spf13/cobra"
16
19
)
17
20
@@ -143,3 +146,82 @@ func CLIChecks(cliData api.CLIData, submitBaseURL *string) (results []api.CLISte
143
146
}
144
147
return results
145
148
}
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