diff options
| author | moxie <moxie@3kgcat.fi> | 2026-03-13 09:58:53 +0200 |
|---|---|---|
| committer | moxie <moxie@3kgcat.fi> | 2026-03-13 09:58:53 +0200 |
| commit | bc2944651f4dabc68d7f34c796400d80ba132016 (patch) | |
| tree | 3655716442a24ccb758983f0ddc89222916f64c1 /lua/muwiki/paths.lua | |
chore: init
Diffstat (limited to 'lua/muwiki/paths.lua')
| -rw-r--r-- | lua/muwiki/paths.lua | 88 |
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 |
