aboutsummaryrefslogtreecommitdiff
path: root/lua/muwiki/paths.lua
diff options
context:
space:
mode:
Diffstat (limited to 'lua/muwiki/paths.lua')
-rw-r--r--lua/muwiki/paths.lua88
1 files changed, 88 insertions, 0 deletions
diff --git a/lua/muwiki/paths.lua b/lua/muwiki/paths.lua
new file mode 100644
index 0000000..aa07776
--- /dev/null
+++ b/lua/muwiki/paths.lua
@@ -0,0 +1,88 @@
+
+local M = {}
+
+function M.get_path_type(path)
+ if path:sub(1, 1) == '/' then
+ return 'absolute'
+ elseif path:sub(1, 1) == '~' then
+ return 'home'
+ else
+ return 'relative'
+ end
+end
+
+function M.resolve_relative(path, base)
+ local result
+
+ if vim.startswith(path, './') then
+ result = vim.fs.joinpath(base, path:sub(3))
+ elseif vim.startswith(path, '../') then
+ local current_base = base
+ local remaining = path
+
+ while vim.startswith(remaining, '../') do
+ current_base = vim.fs.dirname(current_base)
+ remaining = remaining:sub(4)
+ end
+
+ result = vim.fs.joinpath(current_base, remaining)
+ else
+ result = vim.fs.joinpath(base, path)
+ end
+
+ return vim.fs.normalize(result)
+end
+
+function M.resolve(filepath, current_file)
+ local path_type = M.get_path_type(filepath)
+
+ if path_type == 'absolute' then
+ return vim.fs.normalize(filepath)
+ elseif path_type == 'home' then
+ return vim.fs.normalize(filepath)
+ else
+ local base = current_file and vim.fs.dirname(current_file)
+ or vim.fs.dirname(vim.api.nvim_buf_get_name(0))
+ return M.resolve_relative(filepath, base)
+ end
+end
+
+function M.strip_file_protocol(url)
+ return url:gsub('^file://', '')
+end
+
+function M.is_within_wiki(filepath, wiki_root)
+ local real_path = vim.fn.resolve(filepath)
+ local real_root = vim.fn.resolve(wiki_root)
+
+ local normalized_path = vim.fs.normalize(real_path)
+ local normalized_root = vim.fs.normalize(real_root)
+
+ return vim.startswith(normalized_path, normalized_root)
+end
+
+function M.validate_within_wiki(resolved_path, wiki_root, original_path)
+ if not M.is_within_wiki(resolved_path, wiki_root) then
+ vim.notify(
+ string.format('Warning: Resolved path outside wiki root: %s', original_path),
+ vim.log.levels.WARN
+ )
+ end
+ return resolved_path
+end
+
+local ALLOWED_SCHEMES = {
+ http = true,
+ https = true,
+ file = true,
+}
+
+function M.validate_url_scheme(url)
+ local scheme = url:match('^([a-zA-Z]+)://')
+ if scheme and not ALLOWED_SCHEMES[scheme:lower()] then
+ return false, string.format('URL scheme not allowed: %s', scheme)
+ end
+ return true, nil
+end
+
+return M