- Added read-write access to the darktable SQLite catalog for module parameter edits. - Implemented new endpoints for exporting images and retrieving full-resolution images. - Introduced PATCH method for updating module parameters with optional preview. - Added comprehensive tests for new API functionalities, including module retrieval and error handling. - Updated CORS headers to support new HTTP methods. - Created detailed documentation for new API endpoints and module operations.
69 lines
2.1 KiB
Lua
69 lines
2.1 KiB
Lua
-- Simple radix-style HTTP router.
|
|
-- Supports static segments and named captures (:name).
|
|
-- Usage:
|
|
-- router.get("/api/v1/images", handler)
|
|
-- router.get("/api/v1/images/:id", handler)
|
|
-- router.post("/oauth/token", handler)
|
|
--
|
|
-- local handler, params = router.match("GET", "/api/v1/images/42")
|
|
-- -- handler = <function>, params = { id = "42" }
|
|
local M = {}
|
|
|
|
local routes = {} -- { method, pattern_parts, handler }
|
|
|
|
-- Convert a route pattern like "/api/v1/images/:id/preview" into a segment list.
|
|
local function compile(pattern)
|
|
local parts = {}
|
|
-- Strip leading slash so the segment list aligns with the path splitter below.
|
|
for seg in (pattern:gsub("^/", "") .. "/"):gmatch("([^/]*)/") do
|
|
if seg:sub(1,1) == ":" then
|
|
parts[#parts+1] = { capture = seg:sub(2) }
|
|
else
|
|
parts[#parts+1] = { literal = seg }
|
|
end
|
|
end
|
|
return parts
|
|
end
|
|
|
|
local function register(method, pattern, handler)
|
|
routes[#routes+1] = { method = method:upper(), parts = compile(pattern), handler = handler }
|
|
end
|
|
|
|
function M.get(pattern, handler) register("GET", pattern, handler) end
|
|
function M.post(pattern, handler) register("POST", pattern, handler) end
|
|
function M.put(pattern, handler) register("PUT", pattern, handler) end
|
|
function M.patch(pattern, handler) register("PATCH", pattern, handler) end
|
|
function M.delete(pattern, handler) register("DELETE", pattern, handler) end
|
|
|
|
-- Match a request against registered routes.
|
|
-- Returns: handler, path_params or nil, nil
|
|
function M.match(method, path)
|
|
-- Split path into segments
|
|
local segs = {}
|
|
for seg in (path:gsub("^/","") .. "/"):gmatch("([^/]*)/") do
|
|
segs[#segs+1] = seg
|
|
end
|
|
|
|
method = method:upper()
|
|
|
|
for _, route in ipairs(routes) do
|
|
if route.method == method and #route.parts == #segs then
|
|
local params = {}
|
|
local matched = true
|
|
for i, part in ipairs(route.parts) do
|
|
if part.capture then
|
|
params[part.capture] = segs[i]
|
|
elseif part.literal ~= segs[i] then
|
|
matched = false
|
|
break
|
|
end
|
|
end
|
|
if matched then return route.handler, params end
|
|
end
|
|
end
|
|
|
|
return nil, nil
|
|
end
|
|
|
|
return M
|