refactor: move TodoMVC example into example/ directory
- example/todomvc/pocketbook/todomvc.cljs — app source - example/todomvc/todomvc.html — page - example/todomvc/js/ — compiled output (gitignored) Server static file serving is now filesystem-based via --static-dir flag instead of classpath resources. No static dir by default (API only); bb server passes --static-dir example/todomvc. Removed resources/public/ — library has no bundled static assets.
This commit is contained in:
@@ -20,10 +20,11 @@
|
||||
;; ---------------------------------------------------------------------------
|
||||
|
||||
(def default-config
|
||||
{:port 8090
|
||||
:db-path "pocketbook.db"
|
||||
:users nil ;; nil = no auth, or {"alice" {:token "abc" :groups #{"todo"}}}
|
||||
:cors true})
|
||||
{:port 8090
|
||||
:db-path "pocketbook.db"
|
||||
:static-dir nil ;; nil = no static serving, or path like "example/todomvc"
|
||||
:users nil ;; nil = no auth, or {"alice" {:token "abc" :groups #{"todo"}}}
|
||||
:cors true})
|
||||
|
||||
;; ---------------------------------------------------------------------------
|
||||
;; Auth
|
||||
@@ -135,15 +136,19 @@
|
||||
(subs path (inc i)))))
|
||||
|
||||
(defn- serve-static
|
||||
"Attempt to serve a static file from resources/public. Returns response or nil."
|
||||
[uri]
|
||||
(let [path (str "public" (if (= "/" uri) "/todomvc.html" uri))
|
||||
resource (io/resource path)]
|
||||
(when resource
|
||||
{:status 200
|
||||
:headers {"Content-Type" (get content-types (ext path) "application/octet-stream")
|
||||
"Cache-Control" "no-cache"}
|
||||
:body (io/input-stream resource)})))
|
||||
"Attempt to serve a static file from a directory. Returns response or nil."
|
||||
[static-dir uri]
|
||||
(when static-dir
|
||||
(let [rel (if (= "/" uri) "/todomvc.html" uri)
|
||||
file (io/file static-dir (subs rel 1))]
|
||||
(when (and (.isFile file) (.canRead file)
|
||||
;; Prevent path traversal
|
||||
(.startsWith (.toPath file) (.toPath (io/file static-dir))))
|
||||
{:status 200
|
||||
:headers {"Content-Type" (get content-types (ext (.getName file))
|
||||
"application/octet-stream")
|
||||
"Cache-Control" "no-cache"}
|
||||
:body (io/input-stream file)}))))
|
||||
|
||||
;; ---------------------------------------------------------------------------
|
||||
;; Ring handler
|
||||
@@ -171,7 +176,7 @@
|
||||
|
||||
;; Static files (including / → todomvc.html)
|
||||
:else
|
||||
(or (serve-static (:uri req))
|
||||
(or (serve-static (:static-dir config) (:uri req))
|
||||
{:status 404
|
||||
:headers {"Content-Type" "text/plain"}
|
||||
:body "Not found"}))]
|
||||
@@ -195,7 +200,9 @@
|
||||
(println (str "🔶 Pocketbook server running on http://localhost:" (:port config)))
|
||||
(println (str " Database: " (:db-path config)))
|
||||
(println (str " Auth: " (if (:users config) "enabled" "disabled")))
|
||||
(println (str " TodoMVC: http://localhost:" (:port config) "/todomvc.html"))
|
||||
(when (:static-dir config)
|
||||
(println (str " Static: " (:static-dir config)))
|
||||
(println (str " App: http://localhost:" (:port config) "/")))
|
||||
{:stop server
|
||||
:ds ds
|
||||
:config config})))
|
||||
@@ -210,11 +217,13 @@
|
||||
;; ---------------------------------------------------------------------------
|
||||
|
||||
(defn -main [& args]
|
||||
(let [port (some-> (first args) parse-long)
|
||||
db-path (second args)
|
||||
config (cond-> {}
|
||||
port (assoc :port port)
|
||||
db-path (assoc :db-path db-path))]
|
||||
(let [opts (apply hash-map (map #(if (str/starts-with? % "--")
|
||||
(keyword (subs % 2))
|
||||
%)
|
||||
args))
|
||||
config (cond-> {}
|
||||
(:port opts) (assoc :port (parse-long (:port opts)))
|
||||
(:db-path opts) (assoc :db-path (:db-path opts))
|
||||
(:static-dir opts) (assoc :static-dir (:static-dir opts)))]
|
||||
(start! config)
|
||||
;; Keep the server running
|
||||
@(promise)))
|
||||
|
||||
Reference in New Issue
Block a user