@cldmv/slothlet 3.15.1 → 3.15.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -14,4 +14,4 @@
14
14
  limitations under the License.
15
15
  */
16
16
 
17
- import{ComponentBase}from"#factories/component-base";import{fsp,path,url,createRequire}from"@cldmv/slothlet/helpers/platform";import{compilePattern}from"@cldmv/slothlet/helpers/pattern-matcher";import{isFrameworkReservedKey}from"#handlers/unified-wrapper";import{SlothletWarning}from"@cldmv/slothlet/errors";const RUNTIME_EXTERNALIZED=!("env"in import.meta);function warnIfCoverageWithoutImporter(config,{worker=globalThis.__vitest_worker__,externalized=RUNTIME_EXTERNALIZED}={}){if(worker?.config?.coverage?.enabled!==true)return false;if(!externalized)return false;if(typeof config?.import==="function")return false;if(config?.silent)return false;new SlothletWarning("WARNING_COVERAGE_IMPORTER_UNSET",{});return true}function compileHidden(globs){if(!globs)return null;const list=Array.isArray(globs)?globs:[globs];const rules=[];for(const g of list){if(typeof g!=="string"||g.length===0)continue;const negated=g.startsWith("!");const body=(negated?g.slice(1):g).replace(/\//g,".");if(body.length===0)continue;rules.push({negated,match:compilePattern(body)})}if(!rules.length)return null;return relDotted=>{let hidden=false;for(const rule of rules){if(rule.match(relDotted))hidden=!rule.negated}return hidden}}class Loader extends ComponentBase{static slothletProperty="loader";constructor(slothlet){super(slothlet)}async loadModule(filePath,instanceID,moduleID,cacheBust=null){try{if(this.slothlet.envTarget==="browser"){return this.#loadModuleBrowser(filePath)}if(filePath.endsWith(".cjs")){return this.#loadCJSIsolated(filePath)}const isTypeScript=filePath.endsWith(".ts")||filePath.endsWith(".mts");const typescriptConfig=this.slothlet.config?.typescript;let moduleUrl;if(isTypeScript&&typescriptConfig?.enabled){const mode=typescriptConfig.mode;if(mode==="strict"){if(!typescriptConfig.types?.output){throw new this.SlothletError("TS_STRICT_REQUIRES_OUTPUT",{},null,{validationError:true})}if(!typescriptConfig.types?.interfaceName){throw new this.SlothletError("TS_STRICT_REQUIRES_INTERFACE_NAME",{},null,{validationError:true})}if(!this.slothlet._typesGenerated){const{fork}=await import("child_process");const path2=await import("path");const{fileURLToPath}=await import("url");const __dirname=path2.dirname(fileURLToPath(import.meta.url));const scriptPath=path2.resolve(__dirname,"../../../tools/build/generate-types-worker.mjs");const childConfig=JSON.stringify({dir:this.slothlet.config.root||this.slothlet.config.dir,mode:"eager",typescript:{enabled:true,mode:"fast"},types:typescriptConfig.types});await new Promise((resolve,reject)=>{const child=fork(scriptPath,[],{stdio:["pipe","pipe","pipe","ipc"],env:{...process.env,SLOTHLET_CONFIG:childConfig}});let errorOutput="";child.stderr?.on("data",data=>{errorOutput+=data.toString()});child.on("message",msg=>{if(msg.type==="success"){this.slothlet._typesGenerated=true;resolve()}else if(msg.type==="error"){reject(new this.SlothletError("TS_TYPE_GENERATION_FAILED",{},{message:msg.error}))}});child.on("error",error=>{reject(new this.SlothletError("TS_TYPE_GENERATION_FORK_FAILED",{},error))});child.on("exit",code=>{if(code!==0&&!this.slothlet._typesGenerated){reject(new this.SlothletError("TS_TYPE_GENERATION_PROCESS_EXITED",{code,output:errorOutput},null,{validationError:true}))}})})}const{transformTypeScriptStrict,writeTransformedToCache,formatDiagnostics}=await import("@cldmv/slothlet/processors/typescript");const strictTransform=async tsPath=>{const result=await transformTypeScriptStrict(tsPath,{target:typescriptConfig.target,module:typescriptConfig.module,strict:typescriptConfig.strict,typeDefinitionPath:typescriptConfig.types.output,compilerOptions:typescriptConfig.compilerOptions});if(result.diagnostics&&result.diagnostics.length>0){const ts=await import("typescript");const errors=formatDiagnostics(result.diagnostics,ts.default);const error=new this.SlothletError("TS_TYPE_CHECK_ERRORS",{filePath:tsPath,errors:errors.join("\n")},null,{validationError:true});error.diagnostics=result.diagnostics;throw error}return result.code};const entryCode=await strictTransform(filePath);moduleUrl=await this.#buildTypescriptModuleUrl(writeTransformedToCache,filePath,entryCode,instanceID,moduleID,cacheBust,strictTransform)}else{const{transformTypeScript,writeTransformedToCache}=await import("@cldmv/slothlet/processors/typescript");const transformOptions={target:typescriptConfig.target,sourcemap:typescriptConfig.sourcemap};const transformedCode=await transformTypeScript(filePath,transformOptions);const transform=tsPath=>transformTypeScript(tsPath,transformOptions);moduleUrl=await this.#buildTypescriptModuleUrl(writeTransformedToCache,filePath,transformedCode,instanceID,moduleID,cacheBust,transform)}}else{const fileUrl=url.pathToFileURL(filePath).href;moduleUrl=`${fileUrl}?slothlet_instance=${instanceID}`;if(moduleID){moduleUrl+=`&module=${moduleID}`}if(cacheBust){moduleUrl+=`&_reload=${cacheBust}`}}const customImport=this.slothlet?.config?.import;const module=customImport?await customImport(moduleUrl):await import(moduleUrl);return module}catch(error){throw new this.SlothletError("MODULE_IMPORT_FAILED",{modulePath:filePath},error)}}#loadCJSIsolated(filePath){const requireFn=createRequire(filePath);const resolved=requireFn.resolve(filePath);delete requireFn.cache[resolved];const exports=requireFn(resolved);delete requireFn.cache[resolved];const namespace={default:exports};if(exports!==null&&typeof exports==="object"){for(const key of Object.keys(exports)){if(key!=="default"){namespace[key]=exports[key]}}}return namespace}async#buildTypescriptModuleUrl(writeTransformedToCache,filePath,code,instanceID,moduleID,cacheBust,transform){const{url:url2,cacheDir}=await writeTransformedToCache(filePath,code,instanceID,transform);(this.slothlet._typescriptCacheDirs??=new Set).add(cacheDir);let moduleUrl=`${url2}?slothlet_instance=${instanceID}`;if(moduleID){moduleUrl+=`&module=${moduleID}`}if(cacheBust){moduleUrl+=`&_reload=${cacheBust}`}return moduleUrl}async scanDirectory(dir,options={}){if(this.slothlet.envTarget==="browser"){return this.#scanDirectoryBrowser(dir,options)}const typescriptConfig=this.slothlet.config?.typescript;const defaultExtensions=[".mjs",".cjs",".js"];const typescriptExtensions=typescriptConfig?.enabled?[".ts",".mts"]:[];const allExtensions=[...defaultExtensions,...typescriptExtensions];const{recursive=true,extensions=allExtensions,isRootScan=true,currentDepth=0,maxDepth=Infinity,fileFilter=null,hidden=null,scanHiddenFolders=false,rootDir=dir}=options;const hiddenMatcher=typeof hidden==="function"?hidden:compileHidden(hidden);const apiRel=p=>path.relative(rootDir,p).split(path.sep).join(".");const hasHiddenPrefix=name=>name.startsWith(".")||name.startsWith("__");try{await fsp.stat(dir)}catch(error){throw new this.SlothletError("INVALID_DIRECTORY",{dir},error)}const structure={files:[],directories:[]};const entries=await fsp.readdir(dir,{withFileTypes:true});for(const entry of entries){const fullPath=path.join(dir,entry.name);if(entry.isDirectory()){if(fileFilter){continue}if(!scanHiddenFolders&&hasHiddenPrefix(entry.name)){continue}if(hiddenMatcher&&hiddenMatcher(apiRel(fullPath))){continue}if(recursive&&currentDepth<maxDepth){const subStructure=await this.scanDirectory(fullPath,{...options,isRootScan:false,currentDepth:currentDepth+1,hidden:hiddenMatcher,scanHiddenFolders,rootDir});if(subStructure.files.length===0&&subStructure.directories.length===0){continue}structure.directories.push({path:fullPath,name:entry.name,children:subStructure})}}else if(entry.isFile()){const ext=path.extname(entry.name);if(extensions.includes(ext)){if(hasHiddenPrefix(entry.name)){continue}if(fileFilter&&!fileFilter(entry.name)){continue}const nameWithoutExt=path.basename(entry.name,ext);if(hiddenMatcher&&hiddenMatcher(apiRel(path.join(dir,nameWithoutExt)))){continue}if(isFrameworkReservedKey(nameWithoutExt)){throw new this.SlothletError("MODULE_RESERVED_FILENAME",{file:entry.name,dir},null,{validationError:true})}structure.files.push({path:fullPath,name:nameWithoutExt,fullName:entry.name,moduleID:this.slothlet.helpers.sanitize.getModuleId(fullPath,dir)})}}}if(isRootScan&&structure.files.length===0&&structure.directories.length===0&&!this.____config?.silent){new this.SlothletWarning("WARN_DIRECTORY_EMPTY",{dir,resolvedPath:path.resolve(dir)})}return structure}#scanDirectoryBrowser(dir,options={}){const manifest=this.slothlet.config?.manifest;if(!manifest){throw new this.SlothletError("INVALID_CONFIG_BROWSER_REQUIRES_MANIFEST",{},null,{validationError:true})}const configBase=(this.slothlet.config?.dir||"").replace(/\/$/,"");let relativePath=(dir||"").replace(/\/$/,"");if(configBase&&relativePath.startsWith(configBase)){relativePath=relativePath.slice(configBase.length).replace(/^\/|\/$/g,"")}const isRoot=!relativePath||relativePath==="/"||relativePath===".";const node=isRoot?manifest:this.#findManifestNode(manifest,relativePath);if(!node){throw new this.SlothletError("INVALID_DIRECTORY",{dir},null)}return this.#manifestNodeToStructure(node,dir,options)}#findManifestNode(node,targetPath){const normalised=targetPath.replace(/\\/g,"/").replace(/^\/|\/$/g,"");for(const dir of node.directories||[]){const dirPath=(dir.path||dir.name||"").replace(/\\/g,"/").replace(/^\/|\/$/g,"");if(dirPath===normalised)return dir.children||dir;const found=this.#findManifestNode(dir.children||dir,normalised);if(found)return found}return null}#manifestNodeToStructure(node,rootPath,options={}){const{fileFilter=null}=options;const ALLOWED_EXTS=[".mjs",".cjs",".js"];const structure={files:[],directories:[]};for(const file of node.files||[]){const filePath=file.path||file.relativePath||"";const fullName=file.fullName||filePath.split("/").pop();const lastDot=fullName.lastIndexOf(".");const ext=lastDot>=0?fullName.slice(lastDot):"";if(!ALLOWED_EXTS.includes(ext))continue;if(fullName.startsWith("__"))continue;if(fileFilter&&!fileFilter(fullName))continue;const name=file.name||(lastDot>=0?fullName.slice(0,lastDot):fullName);if(isFrameworkReservedKey(name)){throw new this.SlothletError("MODULE_RESERVED_FILENAME",{file:fullName,dir:rootPath},null,{validationError:true})}structure.files.push({path:filePath,name,fullName,moduleID:this.slothlet.helpers.sanitize.getModuleId(filePath,rootPath)})}if(!fileFilter){for(const dir of node.directories||[]){const dirPath=dir.path||dir.name||"";structure.directories.push({path:dirPath,name:dir.name||dirPath.split("/").pop(),children:this.#manifestNodeToStructure(dir.children||dir,dirPath,options)})}}return structure}async#loadModuleBrowser(filePath){const resolveModuleSpecifier=this.slothlet.config?.resolveModuleSpecifier??(({path:p})=>{const base=this.slothlet.config?.base??this.slothlet.config?.dir??"";const leadingSlash=base.startsWith("/")?"":"/";const baseUrl=/^[a-zA-Z][\w+\-.]*:\/\//.test(base)?base.endsWith("/")?base:base+"/":"file://"+leadingSlash+base.replace(/\/?$/,"/");return new URL(p,baseUrl).href});const fullName=filePath.split("/").pop();const lastDot=fullName.lastIndexOf(".");const name=lastDot>=0?fullName.slice(0,lastDot):fullName;const specifier=resolveModuleSpecifier({path:filePath,name,fullName});const module=await import(specifier);return module}extractExports(module){const exports={};if(module.default!==void 0){exports.default=module.default}for(const key of Object.keys(module)){if(key!=="default"&&key!=="module.exports"&&typeof key==="string"){if(isFrameworkReservedKey(key)){throw new this.SlothletError("MODULE_RESERVED_EXPORT",{name:key},null,{validationError:true})}exports[key]=module[key]}}if(exports.default&&typeof exports.default==="object"&&exports.default!==null&&"default"in exports.default){const rootNamedKeys=Object.keys(exports).filter(k=>k!=="default"&&k!=="module.exports");const defaultKeys=Object.keys(exports.default).filter(k=>k!=="default");const isCJSPattern=rootNamedKeys.every(k=>k in exports.default);if(isCJSPattern&&defaultKeys.length>0){exports.default=exports.default.default}}return exports}}export{Loader,warnIfCoverageWithoutImporter};
17
+ import{ComponentBase}from"#factories/component-base";import{DEFAULT_API_DEPTH}from"@cldmv/slothlet/helpers/defaults";import{fsp,path,url,createRequire}from"@cldmv/slothlet/helpers/platform";import{compilePattern}from"@cldmv/slothlet/helpers/pattern-matcher";import{isFrameworkReservedKey}from"#handlers/unified-wrapper";import{SlothletWarning}from"@cldmv/slothlet/errors";const RUNTIME_EXTERNALIZED=!("env"in import.meta);function warnIfCoverageWithoutImporter(config,{worker=globalThis.__vitest_worker__,externalized=RUNTIME_EXTERNALIZED}={}){if(worker?.config?.coverage?.enabled!==true)return false;if(!externalized)return false;if(typeof config?.import==="function")return false;if(config?.silent)return false;new SlothletWarning("WARNING_COVERAGE_IMPORTER_UNSET",{});return true}function compileHidden(globs){if(!globs)return null;const list=Array.isArray(globs)?globs:[globs];const rules=[];for(const g of list){if(typeof g!=="string"||g.length===0)continue;const negated=g.startsWith("!");const body=(negated?g.slice(1):g).replace(/\//g,".");if(body.length===0)continue;rules.push({negated,match:compilePattern(body)})}if(!rules.length)return null;return relDotted=>{let hidden=false;for(const rule of rules){if(rule.match(relDotted))hidden=!rule.negated}return hidden}}class Loader extends ComponentBase{static slothletProperty="loader";constructor(slothlet){super(slothlet)}async loadModule(filePath,instanceID,moduleID,cacheBust=null){try{if(this.slothlet.envTarget==="browser"){return this.#loadModuleBrowser(filePath)}if(filePath.endsWith(".cjs")){return this.#loadCJSIsolated(filePath)}const isTypeScript=filePath.endsWith(".ts")||filePath.endsWith(".mts");const typescriptConfig=this.slothlet.config?.typescript;let moduleUrl;if(isTypeScript&&typescriptConfig?.enabled){const mode=typescriptConfig.mode;if(mode==="strict"){if(!typescriptConfig.types?.output){throw new this.SlothletError("TS_STRICT_REQUIRES_OUTPUT",{},null,{validationError:true})}if(!typescriptConfig.types?.interfaceName){throw new this.SlothletError("TS_STRICT_REQUIRES_INTERFACE_NAME",{},null,{validationError:true})}if(!this.slothlet._typesGenerated){const{fork}=await import("child_process");const path2=await import("path");const{fileURLToPath}=await import("url");const __dirname=path2.dirname(fileURLToPath(import.meta.url));const scriptPath=path2.resolve(__dirname,"../../../tools/build/generate-types-worker.mjs");const childConfig=JSON.stringify({dir:this.slothlet.config.root||this.slothlet.config.dir,mode:"eager",typescript:{enabled:true,mode:"fast"},types:typescriptConfig.types});await new Promise((resolve,reject)=>{const child=fork(scriptPath,[],{stdio:["pipe","pipe","pipe","ipc"],env:{...process.env,SLOTHLET_CONFIG:childConfig}});let errorOutput="";child.stderr?.on("data",data=>{errorOutput+=data.toString()});child.on("message",msg=>{if(msg.type==="success"){this.slothlet._typesGenerated=true;resolve()}else if(msg.type==="error"){reject(new this.SlothletError("TS_TYPE_GENERATION_FAILED",{},{message:msg.error}))}});child.on("error",error=>{reject(new this.SlothletError("TS_TYPE_GENERATION_FORK_FAILED",{},error))});child.on("exit",code=>{if(code!==0&&!this.slothlet._typesGenerated){reject(new this.SlothletError("TS_TYPE_GENERATION_PROCESS_EXITED",{code,output:errorOutput},null,{validationError:true}))}})})}const{transformTypeScriptStrict,writeTransformedToCache,formatDiagnostics}=await import("@cldmv/slothlet/processors/typescript");const strictTransform=async tsPath=>{const result=await transformTypeScriptStrict(tsPath,{target:typescriptConfig.target,module:typescriptConfig.module,strict:typescriptConfig.strict,typeDefinitionPath:typescriptConfig.types.output,compilerOptions:typescriptConfig.compilerOptions});if(result.diagnostics&&result.diagnostics.length>0){const ts=await import("typescript");const errors=formatDiagnostics(result.diagnostics,ts.default);const error=new this.SlothletError("TS_TYPE_CHECK_ERRORS",{filePath:tsPath,errors:errors.join("\n")},null,{validationError:true});error.diagnostics=result.diagnostics;throw error}return result.code};const entryCode=await strictTransform(filePath);moduleUrl=await this.#buildTypescriptModuleUrl(writeTransformedToCache,filePath,entryCode,instanceID,moduleID,cacheBust,strictTransform)}else{const{transformTypeScript,writeTransformedToCache}=await import("@cldmv/slothlet/processors/typescript");const transformOptions={target:typescriptConfig.target,sourcemap:typescriptConfig.sourcemap};const transformedCode=await transformTypeScript(filePath,transformOptions);const transform=tsPath=>transformTypeScript(tsPath,transformOptions);moduleUrl=await this.#buildTypescriptModuleUrl(writeTransformedToCache,filePath,transformedCode,instanceID,moduleID,cacheBust,transform)}}else{const fileUrl=url.pathToFileURL(filePath).href;moduleUrl=`${fileUrl}?slothlet_instance=${instanceID}`;if(moduleID){moduleUrl+=`&module=${moduleID}`}if(cacheBust){moduleUrl+=`&_reload=${cacheBust}`}}const customImport=this.slothlet?.config?.import;const module=customImport?await customImport(moduleUrl):await import(moduleUrl);return module}catch(error){throw new this.SlothletError("MODULE_IMPORT_FAILED",{modulePath:filePath},error)}}#loadCJSIsolated(filePath){const requireFn=createRequire(filePath);const resolved=requireFn.resolve(filePath);delete requireFn.cache[resolved];const exports=requireFn(resolved);delete requireFn.cache[resolved];const namespace={default:exports};if(exports!==null&&typeof exports==="object"){for(const key of Object.keys(exports)){if(key!=="default"){namespace[key]=exports[key]}}}return namespace}async#buildTypescriptModuleUrl(writeTransformedToCache,filePath,code,instanceID,moduleID,cacheBust,transform){const{url:url2,cacheDir}=await writeTransformedToCache(filePath,code,instanceID,transform);(this.slothlet._typescriptCacheDirs??=new Set).add(cacheDir);let moduleUrl=`${url2}?slothlet_instance=${instanceID}`;if(moduleID){moduleUrl+=`&module=${moduleID}`}if(cacheBust){moduleUrl+=`&_reload=${cacheBust}`}return moduleUrl}async scanDirectory(dir,options={}){if(this.slothlet.envTarget==="browser"){return this.#scanDirectoryBrowser(dir,options)}const typescriptConfig=this.slothlet.config?.typescript;const defaultExtensions=[".mjs",".cjs",".js"];const typescriptExtensions=typescriptConfig?.enabled?[".ts",".mts"]:[];const allExtensions=[...defaultExtensions,...typescriptExtensions];const{recursive=true,extensions=allExtensions,isRootScan=true,currentDepth=0,maxDepth=DEFAULT_API_DEPTH,fileFilter=null,hidden=null,scanHiddenFolders=false,rootDir=dir}=options;const hiddenMatcher=typeof hidden==="function"?hidden:compileHidden(hidden);const apiRel=p=>path.relative(rootDir,p).split(path.sep).join(".");const hasHiddenPrefix=name=>name.startsWith(".")||name.startsWith("__");try{await fsp.stat(dir)}catch(error){throw new this.SlothletError("INVALID_DIRECTORY",{dir},error)}const structure={files:[],directories:[]};const entries=await fsp.readdir(dir,{withFileTypes:true});for(const entry of entries){const fullPath=path.join(dir,entry.name);if(entry.isDirectory()){if(fileFilter){continue}if(!scanHiddenFolders&&hasHiddenPrefix(entry.name)){continue}if(hiddenMatcher&&hiddenMatcher(apiRel(fullPath))){continue}if(recursive&&currentDepth<maxDepth){const subStructure=await this.scanDirectory(fullPath,{...options,isRootScan:false,currentDepth:currentDepth+1,hidden:hiddenMatcher,scanHiddenFolders,rootDir});if(subStructure.files.length===0&&subStructure.directories.length===0){continue}structure.directories.push({path:fullPath,name:entry.name,children:subStructure})}}else if(entry.isFile()){const ext=path.extname(entry.name);if(extensions.includes(ext)){if(hasHiddenPrefix(entry.name)){continue}if(fileFilter&&!fileFilter(entry.name)){continue}const nameWithoutExt=path.basename(entry.name,ext);if(hiddenMatcher&&hiddenMatcher(apiRel(path.join(dir,nameWithoutExt)))){continue}if(isFrameworkReservedKey(nameWithoutExt)){throw new this.SlothletError("MODULE_RESERVED_FILENAME",{file:entry.name,dir},null,{validationError:true})}structure.files.push({path:fullPath,name:nameWithoutExt,fullName:entry.name,moduleID:this.slothlet.helpers.sanitize.getModuleId(fullPath,dir)})}}}if(isRootScan&&structure.files.length===0&&structure.directories.length===0&&!this.____config?.silent){new this.SlothletWarning("WARN_DIRECTORY_EMPTY",{dir,resolvedPath:path.resolve(dir)})}return structure}#scanDirectoryBrowser(dir,options={}){const manifest=this.slothlet.config?.manifest;if(!manifest){throw new this.SlothletError("INVALID_CONFIG_BROWSER_REQUIRES_MANIFEST",{},null,{validationError:true})}const configBase=(this.slothlet.config?.dir||"").replace(/\/$/,"");let relativePath=(dir||"").replace(/\/$/,"");if(configBase&&relativePath.startsWith(configBase)){relativePath=relativePath.slice(configBase.length).replace(/^\/|\/$/g,"")}const isRoot=!relativePath||relativePath==="/"||relativePath===".";const node=isRoot?manifest:this.#findManifestNode(manifest,relativePath);if(!node){throw new this.SlothletError("INVALID_DIRECTORY",{dir},null)}return this.#manifestNodeToStructure(node,dir,options)}#findManifestNode(node,targetPath){const normalised=targetPath.replace(/\\/g,"/").replace(/^\/|\/$/g,"");for(const dir of node.directories||[]){const dirPath=(dir.path||dir.name||"").replace(/\\/g,"/").replace(/^\/|\/$/g,"");if(dirPath===normalised)return dir.children||dir;const found=this.#findManifestNode(dir.children||dir,normalised);if(found)return found}return null}#manifestNodeToStructure(node,rootPath,options={}){const{fileFilter=null}=options;const ALLOWED_EXTS=[".mjs",".cjs",".js"];const structure={files:[],directories:[]};for(const file of node.files||[]){const filePath=file.path||file.relativePath||"";const fullName=file.fullName||filePath.split("/").pop();const lastDot=fullName.lastIndexOf(".");const ext=lastDot>=0?fullName.slice(lastDot):"";if(!ALLOWED_EXTS.includes(ext))continue;if(fullName.startsWith("__"))continue;if(fileFilter&&!fileFilter(fullName))continue;const name=file.name||(lastDot>=0?fullName.slice(0,lastDot):fullName);if(isFrameworkReservedKey(name)){throw new this.SlothletError("MODULE_RESERVED_FILENAME",{file:fullName,dir:rootPath},null,{validationError:true})}structure.files.push({path:filePath,name,fullName,moduleID:this.slothlet.helpers.sanitize.getModuleId(filePath,rootPath)})}if(!fileFilter){for(const dir of node.directories||[]){const dirPath=dir.path||dir.name||"";structure.directories.push({path:dirPath,name:dir.name||dirPath.split("/").pop(),children:this.#manifestNodeToStructure(dir.children||dir,dirPath,options)})}}return structure}async#loadModuleBrowser(filePath){const resolveModuleSpecifier=this.slothlet.config?.resolveModuleSpecifier??(({path:p})=>{const base=this.slothlet.config?.base??this.slothlet.config?.dir??"";const leadingSlash=base.startsWith("/")?"":"/";const baseUrl=/^[a-zA-Z][\w+\-.]*:\/\//.test(base)?base.endsWith("/")?base:base+"/":"file://"+leadingSlash+base.replace(/\/?$/,"/");return new URL(p,baseUrl).href});const fullName=filePath.split("/").pop();const lastDot=fullName.lastIndexOf(".");const name=lastDot>=0?fullName.slice(0,lastDot):fullName;const specifier=resolveModuleSpecifier({path:filePath,name,fullName});const module=await import(specifier);return module}extractExports(module){const exports={};if(module.default!==void 0){exports.default=module.default}for(const key of Object.keys(module)){if(key!=="default"&&key!=="module.exports"&&typeof key==="string"){if(isFrameworkReservedKey(key)){throw new this.SlothletError("MODULE_RESERVED_EXPORT",{name:key},null,{validationError:true})}exports[key]=module[key]}}if(exports.default&&typeof exports.default==="object"&&exports.default!==null&&"default"in exports.default){const rootNamedKeys=Object.keys(exports).filter(k=>k!=="default"&&k!=="module.exports");const defaultKeys=Object.keys(exports.default).filter(k=>k!=="default");const isCJSPattern=rootNamedKeys.every(k=>k in exports.default);if(isCJSPattern&&defaultKeys.length>0){exports.default=exports.default.default}}return exports}}export{Loader,warnIfCoverageWithoutImporter};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cldmv/slothlet",
3
- "version": "3.15.1",
3
+ "version": "3.15.3",
4
4
  "moduleVersions": {
5
5
  "lazy": "3.0.0",
6
6
  "eager": "3.0.0",
@@ -0,0 +1,3 @@
1
+ // AUTO-GENERATED by tools/build/build-typestubs.mjs — do not edit.
2
+ // Re-exports the real declarations from @cldmv/slothlet-types (install it for TypeScript support).
3
+ export * from "@cldmv/slothlet-types/helpers/defaults";