diff options
author | colin <colin@cicadas.surf> | 2023-11-18 15:25:51 -0800 |
---|---|---|
committer | colin <colin@cicadas.surf> | 2023-11-18 15:25:51 -0800 |
commit | c201a822f264041a1b9169824c0f9acbfae9cf6e (patch) | |
tree | 47ebbdfeaf4bc184a676537ec03637b3ec023c5d | |
parent | 1d3d018f01ffb71dcdeaa086b3025a00428b45c1 (diff) |
version 1.0
-rw-r--r-- | lazybones-hunchentoot.asd | 10 | ||||
-rw-r--r-- | lazybones.asd | 54 | ||||
-rw-r--r-- | src/backend/hunchentoot.lisp (renamed from lazybones-hunchentoot.lisp) | 11 | ||||
-rw-r--r-- | src/client/dexador.lisp | 205 | ||||
-rw-r--r-- | src/client/parenscript.lisp | 3 | ||||
-rw-r--r-- | src/documentation/markdown.lisp (renamed from lazybones-documentation.lisp) | 15 | ||||
-rw-r--r-- | src/lazybones.lisp (renamed from lazybones.lisp) | 2 | ||||
-rw-r--r-- | src/macros.lisp (renamed from macros.lisp) | 2 | ||||
-rw-r--r-- | src/package.lisp (renamed from package.lisp) | 4 |
9 files changed, 274 insertions, 32 deletions
diff --git a/lazybones-hunchentoot.asd b/lazybones-hunchentoot.asd deleted file mode 100644 index 56ae2c0..0000000 --- a/lazybones-hunchentoot.asd +++ /dev/null @@ -1,10 +0,0 @@ -;;;; lazybones-hunchentoot.asd - -(asdf:defsystem #:lazybones-hunchentoot - :description "hunchentoot backend for lazybones" - :author "Colin Okay <okay@toyful.space>" - :license "AGPLv3" - :version "0.2.1" - :serial t - :depends-on (#:hunchentoot #:lazybones) - :components ((:file "lazybones-hunchentoot"))) diff --git a/lazybones.asd b/lazybones.asd index bd56d95..cb74b04 100644 --- a/lazybones.asd +++ b/lazybones.asd @@ -1,19 +1,61 @@ ;;;; lazybones.asd (asdf:defsystem #:lazybones - :description "http route handling" - :author "Colin Okay <okay@toyful.space>" + :description "Multi-backend HTTP Framework with automatic client and documentation generation. " + :author "Colin <colin@cicadas.surf>" :license "AGPLv3" - :version "0.10.1" + :version "1.0.0" + :pathname "src/" :serial t :depends-on (#:alexandria + #:closer-mop + #:trivial-documentation #:str #:cl-ppcre - #:trivial-documentation #:jonathan #:lisp-namespace) :components ((:file "package") (:file "macros") - (:file "lazybones") - (:file "lazybones-documentation"))) + (:file "lazybones"))) + +(asdf:defsystem #:lazybones/documentation + :description "Generate documentation for a lazybones app's endpoints." + :author "Colin <colin@cicadas.surf>" + :license "AGPLv3" + :depends-on (#:lazybones) + :pathname "src/documentation/" + :serial t + :components ((:file "markdown"))) + +(asdf:defsystem #:lazybones/backend/hunchentoot + :description "hunchentoot backend for lazybones" + :author "Colin <colin@cicadas.surf>" + :license "AGPLv3" + :version "1.0.0" + :depends-on (#:hunchentoot #:lazybones) + :pathname "src/backend/" + :serial t + :components ((:file "hunchentoot"))) + + +(asdf:defsystem #:lazybones/client/parenscript + :description "Generate a JS module for API requests to a lazybones APP." + :author "Colin <colin@cicadas.surf>" + :license "AGPLv3" + :version "1.0.0" + :depends-on (#:parenscript #:lazybones) + :pathname "src/client/" + :serial t + :components ((:file "parenscript"))) + +(asdf:defsystem #:lazybones/client/dexador + :description "Generates a lisp source file for API requests to a lazybones APP using Dexador." + :author "Colin <colin@cicadas.surf>" + :license "AGPLv3" + :version "1.0.0" + :depends-on (#:dexador #:lazybones) + :pathname "src/client/" + :serial t + :components ((:file "dexador"))) + diff --git a/lazybones-hunchentoot.lisp b/src/backend/hunchentoot.lisp index 2b3bf1e..acb15cb 100644 --- a/lazybones-hunchentoot.lisp +++ b/src/backend/hunchentoot.lisp @@ -1,4 +1,4 @@ -;; Copyright (C) 2022 Colin Okay +;; Copyright (C) 2022 colin@cicadas.surf ;; This program is free software: you can redistribute it and/or modify ;; it under the terms of the GNU Affero General Public License as @@ -13,16 +13,13 @@ ;; You should have received a copy of the GNU Affero General Public License ;; along with this program. If not, see <http://www.gnu.org/licenses/>. - -;;;; lazybones-hunchentoot.lisp -- hunchentoot backend for lazybones - -(defpackage #:lazybones.backend/hunchentoot - (:use #:cl #:lazybones.backend) +(defpackage #:lazybones-backend.hunchentoot + (:use #:cl #:lazybones-backend) (:local-nicknames (#:h #:hunchentoot) (#:lzb #:lazybones) (#:a #:alexandria))) -(in-package :lazybones.backend/hunchentoot) +(in-package :lazybones-backend.hunchentoot) ;;; Hunchentoot Acceptor Subclass diff --git a/src/client/dexador.lisp b/src/client/dexador.lisp new file mode 100644 index 0000000..2503b5e --- /dev/null +++ b/src/client/dexador.lisp @@ -0,0 +1,205 @@ +;;;; lazybones-client.lisp -- macro to generate a set of http request functions given an APP instance + +;; Copyright (C) 2022 Colin Okay + +;; 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 <http://www.gnu.org/licenses/>. + + +(defpackage #:lazybones/client.dexador + (:use #:cl) + (:local-nicknames (#:a #:alexandria-2)) + (:export #:generate)) + +(in-package :lazybones/client.dexador) + + + +(defun endpoint-defun-name (ep) + "Returns the string name of a defun for making requests to +endpoint EP." + (with-output-to-string (*standard-output*) + (princ (string-downcase (symbol-name (lazybones::endpoint-method ep)))) + (princ "-") + (loop for (term . more) on (lazybones::endpoint-dispatch-pattern ep) + when (and (stringp term) (plusp (length term))) + do (princ (string-downcase term)) + when (listp term) + do (princ (string-downcase (car term))) + when (and more (plusp (length term))) + do (princ "/")))) + +(defun endpoint-defun-route-var-names (ep) + "Returns a list of strings representing the names of route variables +extracted from endpoint EP, to be used as variable names in the defun +for making requests to that endpoint." + (lazybones::endpoint-route-vars ep)) + +(defun endpoint-defun-query-var-names (ep) + "Returns a list of strings representing the names of query parameter +variables extraced from the endpoint EP, to be used as variable names +in the defun for making request to that endpoint." + (mapcar (a:compose #'symbol-name #'first) + (lazybones::endpoint-params ep))) + + +(defun endpoint-accepts-body-p (ep) + (member (lazybones::endpoint-method ep) '(:post :put :patch)) ) + +(defun endpoint-defun-lambda-list (ep) + "Returns a string representation of the lambda list of the defun +for making requests to endpoint EP." + (format + nil + "(~{~a ~} %host &key ~:[~;%content-type %body ~] %headers %cookies)" + (append + (endpoint-defun-route-var-names ep) + (endpoint-defun-query-var-names ep)) + (endpoint-accepts-body-p ep))) + + +(defun endpoint-defun-dexador-uri-route-format-string (ep) + "Returns a string representing a format string, intended to be + embedded into the body of a defun for making requests to the + endpoint Ep. It is designed to be passed to FORMAT, where route + variables are substituted into the string." + (str:join "/" + (mapcar (lambda (x) (if (listp x) "~a" x)) + (lazybones::endpoint-dispatch-pattern ep)))) + +(defun endpoint-defun-dexador-uri-route-query-format-string (ep) + "Returns a string representing a format string, intended to be + embedded into the body of a defun for making requests to the + endpoint EP. It is desienged to be passed to FORMAT, where query + paramters are substituted into the string, if they exist." + (with-output-to-string (*standard-output*) + (loop + for first = t then nil + for varname in (endpoint-defun-query-var-names ep) + do + (princ "~@[") + (unless first (princ #\&)) + (princ (string-upcase varname)) + (princ "=~a~]")))) + +(defun endpoint-defun-dexador-request-uri (app ep) + "Returns a string representation of code that generates a URI for + passing to the dexador request function within the body of the defun + for making requests to the endpoint EP of the application APP." + (concatenate + 'string + "(format nil " + "\"" + "~a" + (lazybones::app-prefix app) + (endpoint-defun-dexador-uri-route-format-string ep) + "?" + (endpoint-defun-dexador-uri-route-query-format-string ep) + "\" " + "%host " + (str:join " " (endpoint-defun-route-var-names ep)) + " " + (str:join " " (endpoint-defun-query-var-names ep)) + ")")) + +(defun endpoint-defun-body (app ep) + "Returns a string representation of the function body of a defun + for making requests to the endpoint EP in the app APP." + (format + nil + " (dexador:~a~% ~a~%~{ ~a~^~%~})" + (string-downcase (symbol-name (lazybones::endpoint-method ep))) + (endpoint-defun-dexador-request-uri app ep) + (append + (if (endpoint-accepts-body-p ep) + (list ":content %body" + ":cookie-jar %cookies" + ":headers (if %content-type (cons (cons \"Content-Type\" %content-type) %headers) %headers)") + (list ":cookie-jar %cookies" + ":headers %headers"))))) + +(defun generate-defun-for-endpoint (app ep) + "Returns a string representation of a defun form for a function that +makes a request to the endpoint EP." + (format nil + "(defun ~a~% ~a~% ~s~%~a)" + (endpoint-defun-name ep) + (endpoint-defun-lambda-list ep) + (lazybones::endpoint-documentation ep) + (endpoint-defun-body app ep))) + + +(defun all-function-names (app) + (mapcar 'endpoint-defun-name (lazybones::app-endpoints app))) + +(defun app-client-package-name (app) + (format nil "~a-CLIENT" (lazybones::app-name app))) + + +(defun generate-defsystem-for-client-of-app (app) + (with-output-to-string (*standard-output*) + (princ "(asdf:defsystem #:") (princ (app-client-package-name app)) + (terpri) + (princ " :depends-on (#:dexador)") + (terpri) + (princ " :components ((:file ") + (princ #\") + (princ (string-downcase (app-client-package-name app))) + (princ #\") + (princ ")))"))) + + +(defun generate-defpackage-for-client-of-app (app) + (with-output-to-string (out) + (format + out + " +;;;; DO NOT EDIT! THIS FILE HAS BEEN GENERATED BY LAZYBONES-CLIENT + +(defpackage #:~a + (:use :cl) + (:export ~%~{ #:~a~^~%~}))" + (app-client-package-name app) + (all-function-names app)) + (terpri out) + (format out "(in-package :~a)" (app-client-package-name app)) + (terpri out))) + +(defun client-asd-file-name (app) + (format nil "~a.asd" (string-downcase (app-client-package-name app)))) + +(defun client-lisp-file-name (app) + (format nil "~a.lisp" (string-downcase (app-client-package-name app)))) + +(defun generate-client-functions-for-app (app) + (loop for ep in (lazybones::app-endpoints app) + collect (generate-defun-for-endpoint app ep))) + +(defun generate (directory app) + "Generate " + (assert (uiop:directory-exists-p directory)) + + (alexandria:write-string-into-file + (generate-defsystem-for-client-of-app app) + (merge-pathnames (client-asd-file-name app) directory)) + + (alexandria:write-string-into-file + (with-output-to-string (*standard-output*) + (princ (generate-defpackage-for-client-of-app app)) + (princ #\newline) (princ #\newline) + (princ #\newline) (princ #\newline) + (dolist (defun-string (generate-client-functions-for-app app)) + (princ defun-string) + (princ #\newline) (princ #\newline))) + (merge-pathnames (client-lisp-file-name app) directory)) + :ok) diff --git a/src/client/parenscript.lisp b/src/client/parenscript.lisp new file mode 100644 index 0000000..75afbd7 --- /dev/null +++ b/src/client/parenscript.lisp @@ -0,0 +1,3 @@ +(defpackage #:lazybones/client.parenscript + (:use #:cl) + (:export #:generate)) diff --git a/lazybones-documentation.lisp b/src/documentation/markdown.lisp index 9e837d0..5f2b883 100644 --- a/lazybones-documentation.lisp +++ b/src/documentation/markdown.lisp @@ -1,4 +1,4 @@ -;; Copyright (C) 2022 Colin Okay +;; Copyright (C) 2022 colin@cicadas.surf ;; This program is free software: you can redistribute it and/or modify ;; it under the terms of the GNU Affero General Public License as @@ -14,15 +14,20 @@ ;; along with this program. If not, see <http://www.gnu.org/licenses/>. -;;;; lazybones-documentation.lisp -- documenting APP instances +;;;; markdown.lisp -- documenting APP instances -(in-package :lazybones) +(defpackage #:lazybones/documentation.markdown + (:use #:cl) + (:export #:generate)) + +(in-package :lazybones/documentation.markdown) (defun sorted-endpoints (endpoints) (sort (copy-seq endpoints) #'string< :key #'endpoint-route)) -(defun generate-app-documentation (app) - "For now, generates a single Markdown string that documents each endpoint in APP." +(defun generate (app) + "For now, returns a single Markdown formatted string that documents +each endpoint in APP." (symbol-macrolet ((newline (progn (princ #\newline)(princ #\newline)))) (with-slots (title diff --git a/lazybones.lisp b/src/lazybones.lisp index e9adc03..97c7d40 100644 --- a/lazybones.lisp +++ b/src/lazybones.lisp @@ -1,4 +1,4 @@ -;; Copyright (C) 2022 Colin Okay +;; Copyright (C) 2022 colin@cicadas.surf ;; This program is free software: you can redistribute it and/or modify ;; it under the terms of the GNU Affero General Public License as diff --git a/macros.lisp b/src/macros.lisp index 46ac4da..0d941b6 100644 --- a/macros.lisp +++ b/src/macros.lisp @@ -1,4 +1,4 @@ -;; Copyright (C) 2022 Colin Okay +;; Copyright (C) 2022 colin@cicadas.surf ;; This program is free software: you can redistribute it and/or modify ;; it under the terms of the GNU Affero General Public License as diff --git a/package.lisp b/src/package.lisp index 4ed5cdf..04cc5bf 100644 --- a/package.lisp +++ b/src/package.lisp @@ -2,7 +2,7 @@ ;; any backend must implement functions for these ;; use the hunchentoot backend as a reference -(defpackage #:lazybones.backend +(defpackage #:lazybones-backend (:export ;; request functions #:request-url @@ -39,7 +39,7 @@ ;; the symbols exported here are available for end users to use in the ;; building of their apps (defpackage #:lazybones - (:use #:cl #:lazybones.backend) + (:use #:cl #:lazybones-backend) (:local-nicknames (#:a #:alexandria) (#:re #:cl-ppcre)) (:export |