Files
sky_phone-sky-systems/sky_phone/source/shared/custom_app_compat.lua
T
Leon.Schmidt 42ac955052 ADD - expand phone application platform
Add the Companies app, resilient call handling, custom app registry, vendor compatibility, storage policies, frontend bridge, tests, documentation, config, locale, and SQL migrations.
2026-08-11 00:22:39 +02:00

230 lines
7.0 KiB
Lua

SkyPhoneCompatibility = {}
SkyPhoneCompatibility.Providers = {
lb = "lb_phone",
seventeen = "17mov",
high = "high_phone",
quasar = "quasar_v3",
yseries = "yseries",
}
local function normalize_at_resource_url(owner_resource, url, error_prefix)
if type(url) ~= "string" or url == "" then
return nil, "invalid_" .. error_prefix
end
if url:sub(1, 7) == "http://" then
return nil, "insecure_" .. error_prefix
end
if url:sub(1, 1) ~= "@" then
return url
end
local url_owner, url_path = url:match("^@([^/]+)/(.+)$")
if url_owner ~= owner_resource or not url_path then
return nil, error_prefix .. "_owner_mismatch"
end
return owner_resource .. "/" .. url_path
end
local function build_locale_maps(app_name, locales)
local names = {}
local descriptions = {}
if type(locales) == "table" then
for locale, locale_data in pairs(locales) do
if type(locale) == "string" and type(locale_data) == "table" then
if type(locale_data.label) == "string" and locale_data.label ~= "" then
names[locale] = locale_data.label
end
if type(locale_data.description) == "string" and locale_data.description ~= "" then
descriptions[locale] = locale_data.description
end
end
end
end
if not next(names) then
return app_name, app_name
end
for locale, label in pairs(names) do
if not descriptions[locale] then
descriptions[locale] = label
end
end
return names, descriptions
end
function SkyPhoneCompatibility.CopyQuasarData(app_data)
local copy = {}
for key, value in pairs(app_data) do
if key == "iframe" and type(value) == "table" then
copy.iframe = {}
for iframe_key, iframe_value in pairs(value) do
copy.iframe[iframe_key] = iframe_value
end
else
copy[key] = value
end
end
return copy
end
function SkyPhoneCompatibility.BuildLbDefinition(owner_resource, app_data)
if type(app_data) ~= "table" or type(app_data.identifier) ~= "string" then
return nil, "invalid_app_data"
end
local ui, ui_error = normalize_at_resource_url(owner_resource, app_data.ui, "ui")
if not ui then
return nil, ui_error
end
return {
schemaVersion = 1,
id = app_data.identifier,
name = app_data.name,
description = app_data.description,
developer = app_data.developer,
category = app_data.game and "games" or "utilities",
ui = ui,
bridgeMode = "legacy",
icon = app_data.icon,
defaultInstalled = app_data.defaultApp or false,
removable = not app_data.defaultApp,
orientation = app_data.landscape and "landscape" or "portrait",
onInstall = app_data.onInstall,
onOpen = app_data.onOpen or app_data.onUse,
onClose = app_data.onClose,
compatibility = {
provider = SkyPhoneCompatibility.Providers.lb,
apiVersion = 1,
},
}
end
function SkyPhoneCompatibility.Build17MovDefinition(app_data)
if type(app_data) ~= "table" or type(app_data.name) ~= "string" then
return nil, "invalid_app_data"
end
return {
schemaVersion = 1,
id = app_data.name,
name = app_data.label,
description = app_data.description or app_data.label,
category = "utilities",
ui = app_data.ui,
bridgeMode = "legacy",
icon = app_data.icon,
iconBackground = type(app_data.iconBackground) == "string" and app_data.iconBackground or nil,
defaultInstalled = app_data.default or app_data.preInstalled or false,
removable = not app_data.default,
orientation = "portrait",
compatibility = {
provider = SkyPhoneCompatibility.Providers.seventeen,
apiVersion = 1,
},
}
end
function SkyPhoneCompatibility.BuildHighDefinition(owner_resource, app_name, data, locales)
if type(owner_resource) ~= "string" or type(app_name) ~= "string" or type(data) ~= "table" then
return nil, "invalid_app_data"
end
if #app_name > 64 or not app_name:match("^[a-z0-9][a-z0-9._-]+$") then
return nil, "invalid_app_id"
end
local external_url, url_error = normalize_at_resource_url(
owner_resource,
data.externalUrl,
"external_url"
)
if not external_url then
return nil, url_error
end
local name, description = build_locale_maps(app_name, locales)
local icon = type(data.icon) == "table" and data.icon.imageUrl or data.icon
return {
schemaVersion = 1,
id = app_name,
name = name,
description = description,
developer = data.developer,
category = "utilities",
ui = external_url,
bridgeMode = "legacy",
icon = icon,
iconBackground = type(data.icon) == "table" and data.icon.background or nil,
defaultInstalled = data.preAdded or false,
removable = data.removable ~= false,
orientation = "portrait",
compatibility = {
provider = SkyPhoneCompatibility.Providers.high,
apiVersion = 1,
},
}
end
function SkyPhoneCompatibility.BuildQuasarDefinition(app_data)
local iframe_url = type(app_data) == "table"
and type(app_data.iframe) == "table"
and app_data.iframe.url
or nil
if type(app_data) ~= "table"
or type(app_data.id) ~= "string"
or type(app_data.label) ~= "string"
or type(iframe_url) ~= "string"
then
return nil, "invalid_app_data"
end
return {
schemaVersion = 1,
id = app_data.id,
name = app_data.label,
description = app_data.description or app_data.label,
category = "utilities",
ui = iframe_url,
bridgeMode = "legacy",
icon = app_data.icon,
defaultInstalled = app_data.defaultInstalled or false,
removable = true,
orientation = "portrait",
compatibility = {
provider = SkyPhoneCompatibility.Providers.quasar,
apiVersion = 1,
},
}
end
function SkyPhoneCompatibility.BuildYSeriesDefinition(app_data)
if type(app_data) ~= "table" or type(app_data.key) ~= "string" then
return nil, "invalid_app_data"
end
local icon = app_data.icon
if type(icon) == "table" then
icon = icon.yos or icon.humanoid
end
return {
schemaVersion = 1,
id = app_data.key,
name = app_data.name,
description = app_data.description or app_data.name,
category = app_data.game and "games" or "utilities",
ui = app_data.ui,
bridgeMode = "legacy",
icon = icon,
defaultInstalled = app_data.defaultApp or false,
removable = true,
orientation = "portrait",
compatibility = {
provider = SkyPhoneCompatibility.Providers.yseries,
apiVersion = 1,
},
}
end