Commita5fc6ebfRecorded25 Mar 2026Repositorysigil-lemonsqueezy

Remove local url-encode-value and build-query-string, import from (sigil http)

Message

License sub-module now imports url-encode-value directly from (sigil http). Tests updated for uppercase hex encoding (%5B/%5D vs %5b/%5d).

Changed
 src/lemonsqueezy.sgl         | 50 +-------------------------------------------------
 src/lemonsqueezy/license.sgl |  1 +
 test/lemonsqueezy-test.sgl   |  9 +++++----
 3 files changed, 7 insertions(+), 53 deletions(-)
Diff
src/lemonsqueezy.sglmodified
@@ -12,6 +12,7 @@
12
(sigil string)
13
(sigil struct)
14
(sigil json)
+15
(only (sigil http) url-encode-value build-query-string)
16
(sigil http client))
17
18
(export ;; Client
@@ -48,10 +49,6 @@
49
ls-paginate
50
ls-list-params
51
51
;; URL helpers
52
url-encode-value
53
build-query-string
54
52
;; Generic endpoint helpers
53
ls-list-endpoint
54
ls-get-endpoint
@@ -69,51 +66,6 @@
66
(api-key)
67
(base-url default: "https://api.lemonsqueezy.com"))
68
72
;; ---------------------------------------------------------------
73
;; URL encoding helpers
74
;; ---------------------------------------------------------------
75
76
;;; URL-encode a query parameter value (RFC 3986 unreserved chars).
77
(define (url-encode-value s)
78
(let ((len (string-length s)))
79
(let loop ((i 0) (acc '()))
80
(if (>= i len)
81
(list->string (reverse acc))
82
(let ((c (string-ref s i)))
83
(cond
84
((or (char-alphabetic? c)
85
(char-numeric? c)
86
(char=? c #\-)
87
(char=? c #\_)
88
(char=? c #\.)
89
(char=? c #\~))
90
(loop (+ i 1) (cons c acc)))
91
((char=? c #\space)
92
(loop (+ i 1) (cons #\+ acc)))
93
(else
94
(let ((n (char->integer c)))
95
(loop (+ i 1)
96
(append (reverse (string->list
97
(string-append "%"
98
(if (< n 16) "0" "")
99
(number->string n 16))))
100
acc))))))))))
101
102
;;; Build a query string from a list of (key . value) pairs.
103
;;; Pairs with #f values are omitted.
104
(define (build-query-string params)
105
(let ((parts (filter (lambda (p) (cdr p)) params)))
106
(if (null? parts)
107
""
108
(string-append "?"
109
(string-join
110
(map (lambda (p)
111
(string-append (url-encode-value (car p))
112
"="
113
(url-encode-value (cdr p))))
114
parts)
115
"&")))))
116
69
;; ---------------------------------------------------------------
70
;; Internal helpers
71
;; ---------------------------------------------------------------
src/lemonsqueezy/license.sglmodified
@@ -13,6 +13,7 @@
13
(sigil string)
14
(sigil struct)
15
(sigil json)
+16
(only (sigil http) url-encode-value)
17
(sigil http client)
18
(lemonsqueezy))
19
test/lemonsqueezy-test.sglmodified
@@ -10,6 +10,7 @@
10
(sigil json)
11
(sigil crypto)
12
(sigil test)
+13
(only (sigil http) build-query-string)
14
(lemonsqueezy)
15
(lemonsqueezy product)
16
(lemonsqueezy checkout)
@@ -624,14 +625,14 @@
625
(test "page and per-page params"
626
(let ((params (ls-list-params #{ page: 2 per-page: 25 })))
627
(let ((qs (build-query-string params)))
627
(assert-true (string-contains? qs "page%5bnumber%5d=2"))
628
(assert-true (string-contains? qs "page%5bsize%5d=25")))))
+628
(assert-true (string-contains? qs "page%5Bnumber%5D=2"))
+629
(assert-true (string-contains? qs "page%5Bsize%5D=25")))))
630
631
(test "filter params"
632
(let ((params (ls-list-params #{ filter: #{ store_id: "1" status: "active" } })))
633
(let ((qs (build-query-string params)))
633
(assert-true (string-contains? qs "filter%5bstore_id%5d=1"))
634
(assert-true (string-contains? qs "filter%5bstatus%5d=active")))))
+634
(assert-true (string-contains? qs "filter%5Bstore_id%5D=1"))
+635
(assert-true (string-contains? qs "filter%5Bstatus%5D=active")))))
636
637
(test "include param"
638
(let ((params (ls-list-params #{ include: "variants,store" })))