Files
cell/scripts/module_resolver.cm

94 lines
2.4 KiB
Plaintext

// Module resolver for handling different import styles
// Works with the PhysFS mount system set up by shop.js
var ModuleResolver = {}
// Resolve module imports according to the specification
ModuleResolver.resolve = function(request, from_path) {
// Handle scheme-qualified imports
if (request.includes('://')) {
var parts = request.split('://')
var scheme = parts[0]
var path = parts[1]
// Direct mapping to mount points
return '/' + scheme + '/' + path
}
// Handle relative imports
if (request.startsWith('./') || request.startsWith('../')) {
// Relative imports are resolved from the importing module's directory
if (from_path) {
var dir = from_path.substring(0, from_path.lastIndexOf('/'))
return resolve_relative(dir, request)
}
return request
}
// Handle bare imports
// PhysFS will search through all mounted directories
// The mount order ensures proper precedence
return request
}
// Helper to resolve relative paths
function resolve_relative(base, relative) {
var parts = base.split('/')
var rel_parts = relative.split('/')
for (var i = 0; i < rel_parts.length; i++) {
var part = rel_parts[i]
if (part === '.') {
continue
} else if (part === '..') {
parts.pop()
} else {
parts.push(part)
}
}
return parts.join('/')
}
// Get the shop configuration if available
ModuleResolver.get_shop_config = function() {
try {
var shop = use('shop')
if (shop) {
return shop.load_config()
}
} catch (e) {
// Shop not available yet
}
return null
}
// Check if a bare import should be routed to an alias
ModuleResolver.check_alias = function(request) {
var config = ModuleResolver.get_shop_config()
if (!config) return null
var first_segment = request.split('/')[0]
// Check dependencies
if (config.dependencies && config.dependencies[first_segment]) {
return '/' + request
}
// Check aliases
if (config.aliases && config.aliases[first_segment]) {
var actual = config.aliases[first_segment]
return '/' + actual + request.substring(first_segment.length)
}
// Check for single-alias fallback
if (config.dependencies && Object.keys(config.dependencies).length === 1) {
// If only one dependency and no local file matches, route there
var only_dep = Object.keys(config.dependencies)[0]
return '/' + only_dep + '/' + request
}
return null
}
return ModuleResolver