Skip to content

Commit

Permalink
feat(es_extended/imports): add require
Browse files Browse the repository at this point in the history
  • Loading branch information
Kenshiin13 committed Jan 1, 2025
1 parent ab82397 commit 71be624
Showing 1 changed file with 64 additions and 0 deletions.
64 changes: 64 additions & 0 deletions [core]/es_extended/imports.lua
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
ESX = exports["es_extended"]:getSharedObject()
_resourceName = GetCurrentResourceName()

OnPlayerData = function (key, val, last) end

Expand Down Expand Up @@ -42,3 +43,66 @@ if not IsDuplicityVersion() then -- Only register this event for the client
end
end
end

local cachedModules = {} ---@type table<string, any>
local loadingModules = {} ---@type table<string, true?>

---@param modulePath string
---@return string
local function getResourceNameFromModulePath(modulePath)
local externalResourceName = modulePath:match("^@(.-)%.")
if externalResourceName then
return externalResourceName
end

return _resourceName
end

---@param modulePath string
---@return string, number
local function getModuleFilePath(modulePath)
if modulePath:sub(1, 1) == "@" then
modulePath = modulePath:sub(modulePath:find("%.") + 1)
end

return modulePath:gsub("%.", "/")
end

---@param modulePath string
---@return any
function require(modulePath)
assert(type(modulePath) == "string", "Module name must be a string")

if loadingModules[modulePath] then
error(("Circular dependency detected for module '%s'."):format(modulePath))
end

if cachedModules[modulePath] then
return cachedModules[modulePath]
end

loadingModules[modulePath] = true

local resourceName = getResourceNameFromModulePath(modulePath)
local moduleFilePath = getModuleFilePath(modulePath)
local moduleFileContent = LoadResourceFile(resourceName, moduleFilePath .. ".lua")

if not moduleFileContent then
loadingModules[modulePath] = nil
error(("Module '%s' not found in resource '%s'."):format(moduleFilePath, resourceName))
end

local chunk, err = load(moduleFileContent, ("@%s/%s"):format(resourceName, moduleFilePath), "t")

if not chunk then
loadingModules[modulePath] = nil
error(("Failed to load module '%s': %s"):format(moduleFilePath, err))
end

local result = chunk()

cachedModules[modulePath] = result ~= nil and result or true
loadingModules[modulePath] = nil

return result
end

0 comments on commit 71be624

Please sign in to comment.