Some checks failed
Build and Deploy / build-macos (push) Failing after 5s
Build and Deploy / build-windows (CLANG64) (push) Has been cancelled
Build and Deploy / build-linux (push) Failing after 1m30s
Build and Deploy / package-dist (push) Has been skipped
Build and Deploy / deploy-itch (push) Has been skipped
Build and Deploy / deploy-gitea (push) Has been skipped
222 lines
6.3 KiB
JavaScript
222 lines
6.3 KiB
JavaScript
var io = use_embed('io');
|
|
var miniz = use_embed('miniz');
|
|
var os = use_embed('os');
|
|
|
|
Object.defineProperty(Function.prototype, "hashify", {
|
|
value: function () {
|
|
var hash = new Map()
|
|
var fn = this
|
|
function hashified(...args) {
|
|
var key = args[0]
|
|
if (!hash.has(key)) hash.set(key, fn(...args))
|
|
return hash.get(key)
|
|
}
|
|
return hashified
|
|
},
|
|
})
|
|
|
|
// Merge of the old resources.js and packer.js functionalities
|
|
var Resources = {}
|
|
|
|
// Determine the shared library extension based on the OS
|
|
var so_ext
|
|
switch(os.platform()) {
|
|
case 'Windows':
|
|
so_ext = '.dll'
|
|
break
|
|
default:
|
|
so_ext = '.so'
|
|
break
|
|
}
|
|
|
|
// Recognized resource extensions
|
|
Resources.scripts = ["js"]
|
|
Resources.images = ["qoi", "png", "gif", "jpg", "jpeg", "ase", "aseprite"]
|
|
Resources.sounds = ["wav", "flac", "mp3", "qoa"]
|
|
Resources.fonts = ["ttf"]
|
|
Resources.lib = [so_ext]
|
|
|
|
// Helper function: get extension from path in lowercase (e.g., "image.png" -> "png")
|
|
function getExtension(path) {
|
|
var idx = path.lastIndexOf('.')
|
|
if (idx < 0) return ''
|
|
return path.substring(idx + 1).toLowerCase()
|
|
}
|
|
|
|
// Return true if ext is in at least one of the recognized lists
|
|
function isRecognizedExtension(ext) {
|
|
if (!ext) return false
|
|
if (Resources.scripts.includes(ext)) return true
|
|
if (Resources.images.includes(ext)) return true
|
|
if (Resources.sounds.includes(ext)) return true
|
|
if (Resources.fonts.includes(ext)) return true
|
|
if (Resources.lib.includes('.' + ext)) return true // for .so or .dll
|
|
return false
|
|
}
|
|
|
|
function find_in_path(filename, exts = []) {
|
|
if (typeof filename !== 'string') return undefined
|
|
|
|
if (filename.includes('.')) {
|
|
for (var dir of prosperon.PATH) {
|
|
var candidate = dir + filename
|
|
if (io.exists(candidate) && !io.is_directory(candidate)) return candidate
|
|
}
|
|
return undefined
|
|
}
|
|
|
|
for (var dir of prosperon.PATH) {
|
|
// Only check extensions if exts is provided and not empty
|
|
if (exts.length > 0) {
|
|
for (var ext of exts) {
|
|
var candidate = dir + filename + '.' + ext
|
|
if (io.exists(candidate) && !io.is_directory(candidate)) return candidate
|
|
}
|
|
} else {
|
|
// Fallback to extensionless file only if no extensions are specified
|
|
var candidate = dir + filename
|
|
if (io.exists(candidate) && !io.is_directory(candidate)) return candidate
|
|
}
|
|
}
|
|
return undefined
|
|
}
|
|
|
|
// Return a canonical path (the real directory plus the path)
|
|
Resources.canonical = function(file) {
|
|
return io.realdir(file) + file
|
|
}
|
|
|
|
// The resource finders
|
|
Resources.find_image = function(file) {
|
|
return find_in_path(file, Resources.images)
|
|
}.hashify()
|
|
|
|
Resources.find_sound = function(file) {
|
|
return find_in_path(file, Resources.sounds)
|
|
}.hashify()
|
|
|
|
Resources.find_script = function(file) {
|
|
return find_in_path(file, Resources.scripts)
|
|
}.hashify()
|
|
|
|
Resources.find_font = function(file) {
|
|
return find_in_path(file, Resources.fonts)
|
|
}.hashify()
|
|
|
|
// .prosperonignore reading helper
|
|
function read_ignore(dir) {
|
|
var path = dir + '/.prosperonignore'
|
|
var patterns = []
|
|
if (io.exists(path)) {
|
|
var lines = io.slurp(path).split('\n')
|
|
for (var line of lines) {
|
|
line = line.trim()
|
|
if (!line || line.startsWith('#')) continue
|
|
patterns.push(line)
|
|
}
|
|
}
|
|
return patterns
|
|
}
|
|
|
|
// Return a list of recognized files in the directory (and subdirectories),
|
|
// skipping those matched by .prosperonignore. Directory paths are skipped.
|
|
Resources.getAllFiles = function(dir = "") {
|
|
var patterns = read_ignore(dir)
|
|
var all = io.globfs(patterns, dir)
|
|
var results = []
|
|
for (var f of all) {
|
|
var fullPath = dir + '/' + f
|
|
try {
|
|
var st = io.stat(fullPath)
|
|
// skip directories (filesize=0) or unrecognized extension
|
|
if (!st.filesize) continue
|
|
var ext = getExtension(f)
|
|
if (!isRecognizedExtension(ext)) continue
|
|
results.push(fullPath)
|
|
} catch(e) {}
|
|
}
|
|
return results
|
|
}
|
|
Resources.getAllFiles[prosperon.DOC] = `
|
|
Return a list of recognized files in the given directory that are not matched by
|
|
.prosperonignore, skipping directories. Recognized extensions include scripts,
|
|
images, sounds, fonts, and libs.
|
|
|
|
:param dir: The directory to search.
|
|
:return: An array of recognized file paths.
|
|
`
|
|
|
|
// Categorize files by resource type
|
|
Resources.gatherStats = function(filePaths) {
|
|
var stats = {
|
|
scripts:0, images:0, sounds:0, fonts:0, lib:0, other:0, total:filePaths.length
|
|
}
|
|
for (var path of filePaths) {
|
|
var ext = getExtension(path)
|
|
if (Resources.scripts.includes(ext)) {
|
|
stats.scripts++
|
|
continue
|
|
}
|
|
if (Resources.images.includes(ext)) {
|
|
stats.images++
|
|
continue
|
|
}
|
|
if (Resources.sounds.includes(ext)) {
|
|
stats.sounds++
|
|
continue
|
|
}
|
|
if (Resources.fonts.includes(ext)) {
|
|
stats.fonts++
|
|
continue
|
|
}
|
|
// For so_ext, we store it in Resources.lib as ['.so'] or ['.dll'], so match that form
|
|
if (Resources.lib.includes('.' + ext)) {
|
|
stats.lib++
|
|
continue
|
|
}
|
|
stats.other++
|
|
}
|
|
return stats
|
|
}
|
|
Resources.gatherStats[prosperon.DOC] = `
|
|
Analyze a list of recognized files and categorize them by scripts, images, sounds,
|
|
fonts, libs, or other. Return a stats object with these counts and the total.
|
|
|
|
:param filePaths: An array of file paths to analyze.
|
|
:return: { scripts, images, sounds, fonts, lib, other, total }
|
|
`
|
|
|
|
// Create a ZIP of recognized files in a directory, skipping ignored ones, and write to outPath
|
|
Resources.pack = function(dir, outPath) {
|
|
if (!io.exists(dir))
|
|
throw Error("Directory does not exist: " + dir)
|
|
|
|
var files = Resources.getAllFiles(dir)
|
|
var writer = miniz.write(outPath)
|
|
|
|
for (var fullPath of files) {
|
|
try {
|
|
var st = io.stat(fullPath)
|
|
if (!st.filesize) continue // skip directories
|
|
// Path in the ZIP: remove leading dir + '/'
|
|
var pathInZip = fullPath.substring(dir.length + 1)
|
|
var data = io.slurpbytes(fullPath)
|
|
writer.add_file(pathInZip, data)
|
|
} catch(e) {
|
|
// Optionally handle or log errors
|
|
}
|
|
}
|
|
}
|
|
Resources.pack[prosperon.DOC] = `
|
|
Create a ZIP archive of all recognized files (skipping those matched by .prosperonignore)
|
|
in the specified directory and write it to outPath. Recognized extensions are scripts,
|
|
images, sounds, fonts, or libs.
|
|
|
|
:param dir: The directory to zip.
|
|
:param outPath: The path (including filename) for the resulting ZIP file.
|
|
:return: None
|
|
:raises Error: If the directory does not exist.
|
|
`
|
|
|
|
return Resources
|