feat: add quick guide package with initialization and media handling; update test configurations for multiple packages

This commit is contained in:
2025-12-30 01:37:16 +00:00
parent 8c9d501425
commit 589f61faeb
11 changed files with 244 additions and 0 deletions

View File

@@ -16,6 +16,8 @@ export type ModularPackageScriptSeed = {
export type ModularPackageTestConfig = {
/** Lua test script paths relative to scripts/ directory */
scripts?: string[]
/** JSON test case file paths relative to scripts/ directory */
cases?: string[]
}
export type ModularPackageMetadataSeed = {

View File

@@ -22,6 +22,9 @@
"tests": {
"scripts": [
"tests/stats.test.lua"
],
"cases": [
"tests/stats.cases.json"
]
},
"minLevel": 2

View File

@@ -0,0 +1,23 @@
{
"packageId": "quick_guide",
"name": "Quick Guide",
"version": "1.0.0",
"description": "Quick guide builder with steps and media management",
"icon": "static_content/icon.svg",
"author": "MetaBuilder",
"category": "ui",
"dependencies": [],
"exports": {
"components": [
"StepsEditor",
"MediaPane",
"QuickGuideBuilder"
],
"scripts": [
"init",
"steps",
"media"
]
},
"minLevel": 2
}

View File

@@ -0,0 +1,12 @@
-- Quick Guide package initialization
local M = {}
M.name = "quick_guide"
M.version = "1.0.0"
function M.init()
log("Quick Guide package initialized")
return true
end
return M

View File

@@ -0,0 +1,7 @@
{
"scripts": [
{ "file": "init.lua", "name": "init", "category": "lifecycle", "description": "Package initialization" },
{ "file": "steps.lua", "name": "steps", "category": "editor", "description": "Steps editor operations" },
{ "file": "media.lua", "name": "media", "category": "editor", "description": "Media pane operations" }
]
}

View File

@@ -0,0 +1,77 @@
-- Media pane logic for quick guides
local M = {}
-- Validate a URL (basic check)
function M.isValidUrl(url)
if not url or url == "" then
return false
end
return string.match(url, "^https?://") ~= nil
end
-- Check if URL is an image
function M.isImageUrl(url)
if not M.isValidUrl(url) then
return false
end
local patterns = { "%.png$", "%.jpg$", "%.jpeg$", "%.gif$", "%.webp$", "%.svg$" }
for _, pattern in ipairs(patterns) do
if string.match(url:lower(), pattern) then
return true
end
end
return false
end
-- Check if URL is a video embed
function M.isVideoUrl(url)
if not M.isValidUrl(url) then
return false
end
local patterns = { "youtube%.com", "vimeo%.com", "%.mp4$", "%.webm$" }
for _, pattern in ipairs(patterns) do
if string.match(url:lower(), pattern) then
return true
end
end
return false
end
-- Prepare media state
function M.prepareMediaState(props)
props = props or {}
return {
thumbnailUrl = props.thumbnailUrl or "",
videoUrl = props.videoUrl or "",
thumbnailValid = M.isValidUrl(props.thumbnailUrl),
videoValid = M.isValidUrl(props.videoUrl),
thumbnailIsImage = M.isImageUrl(props.thumbnailUrl),
videoIsVideo = M.isVideoUrl(props.videoUrl)
}
end
-- Handle thumbnail change
function M.handleThumbnailChange(state, newUrl)
return {
thumbnailUrl = newUrl,
videoUrl = state.videoUrl,
thumbnailValid = M.isValidUrl(newUrl),
videoValid = state.videoValid,
thumbnailIsImage = M.isImageUrl(newUrl),
videoIsVideo = state.videoIsVideo
}
end
-- Handle video change
function M.handleVideoChange(state, newUrl)
return {
thumbnailUrl = state.thumbnailUrl,
videoUrl = newUrl,
thumbnailValid = state.thumbnailValid,
videoValid = M.isValidUrl(newUrl),
thumbnailIsImage = state.thumbnailIsImage,
videoIsVideo = M.isVideoUrl(newUrl)
}
end
return M

View File

@@ -0,0 +1,107 @@
-- Steps editor logic for quick guides
local M = {}
-- Generate a unique step ID
function M.generateStepId()
return "step_" .. tostring(os.time()) .. "_" .. math.random(1000, 9999)
end
-- Create a new empty step
function M.createStep()
return {
id = M.generateStepId(),
title = "New step",
description = "Describe what happens in this step.",
duration = "1-2 min",
mediaUrl = nil
}
end
-- Update a step in the list
function M.updateStep(steps, stepId, updates)
local result = {}
for i, step in ipairs(steps) do
if step.id == stepId then
local updatedStep = {}
for k, v in pairs(step) do
updatedStep[k] = v
end
for k, v in pairs(updates) do
updatedStep[k] = v
end
result[i] = updatedStep
else
result[i] = step
end
end
return result
end
-- Remove a step from the list
function M.removeStep(steps, stepId)
local result = {}
for _, step in ipairs(steps) do
if step.id ~= stepId then
result[#result + 1] = step
end
end
return result
end
-- Add a new step to the list
function M.addStep(steps)
local newStep = M.createStep()
local result = {}
for i, step in ipairs(steps) do
result[i] = step
end
result[#result + 1] = newStep
return result, newStep
end
-- Reset step IDs to sequential order
function M.resetOrdering(steps)
local result = {}
for i, step in ipairs(steps) do
local resetStep = {}
for k, v in pairs(step) do
resetStep[k] = v
end
resetStep.id = "step_" .. tostring(i)
result[i] = resetStep
end
return result
end
-- Validate a step
function M.validateStep(step)
local errors = {}
if not step.title or step.title == "" then
errors.title = "Title is required"
end
if not step.description or step.description == "" then
errors.description = "Description is required"
end
return { valid = next(errors) == nil, errors = errors }
end
-- Validate all steps
function M.validateAllSteps(steps)
local allErrors = {}
local valid = true
for i, step in ipairs(steps) do
local result = M.validateStep(step)
if not result.valid then
valid = false
allErrors[step.id] = result.errors
end
end
return { valid = valid, errors = allErrors }
end
return M

View File

@@ -23,6 +23,9 @@
"tests": {
"scripts": [
"tests/validate.test.lua"
],
"cases": [
"tests/validate.cases.json"
]
},
"minLevel": 1

View File

@@ -18,6 +18,10 @@
"scripts": [
"tests/check.test.lua",
"tests/levels.test.lua"
],
"cases": [
"tests/check.cases.json",
"tests/levels.cases.json"
]
},
"minLevel": 1

View File

@@ -25,6 +25,9 @@
"tests": {
"scripts": [
"tests/actions.test.lua"
],
"cases": [
"tests/actions.cases.json"
]
},
"minLevel": 4

View File

@@ -23,6 +23,9 @@
"tests": {
"scripts": [
"tests/status.test.lua"
],
"cases": [
"tests/status.cases.json"
]
},
"minLevel": 5