@vlynk-studios/nodulus-core 1.2.0 → 1.2.5
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.
- package/CHANGELOG.md +27 -0
- package/README.md +25 -0
- package/dist/cli/index.js +534 -370
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +22 -31
- package/dist/index.js +114 -93
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/registry.ts","../src/core/errors.ts","../src/identifiers/module.ts","../src/core/caller.ts","../src/identifiers/controller.ts","../src/identifiers/service.ts","../src/identifiers/repository.ts","../src/identifiers/schema.ts","../src/bootstrap/createApp.ts","../src/core/config.ts","../src/core/logger.ts","../src/aliases/resolver.ts","../src/aliases/cache.ts","../src/aliases/getAliases.ts"],"sourcesContent":["import { AsyncLocalStorage } from 'node:async_hooks';\nimport { NodulusError } from './errors.js';\nimport type { \n ModuleEntry, \n RegisteredModule, \n NodulusRegistryAdvanced,\n ModuleOptions,\n ControllerEntry,\n ServiceEntry,\n RepositoryEntry,\n SchemaEntry,\n FileEntry\n} from '../types/index.js';\n\nconst toRegisteredModule = (entry: ModuleEntry): RegisteredModule => ({\n name: entry.name,\n path: entry.path,\n imports: entry.imports,\n exports: entry.exports,\n controllers: entry.controllers.map(c => c.name)\n});\n\n// Extended interface for internal use (includes mutators)\nexport interface InternalRegistry extends NodulusRegistryAdvanced {\n /** Registers an internal module and throws DUPLICATE_MODULE if it already exists */\n registerModule(name: string, options: ModuleOptions, dirPath: string, indexPath: string): void;\n /** Adds an alias to the registry */\n registerAlias(alias: string, path: string): void;\n /** Stores temporary metadata for a recently evaluated controller */\n registerControllerMetadata(entry: ControllerEntry): void;\n /** Returns metadata for all controllers (useful for tests and bootstrap) */\n getAllControllersMetadata(): ControllerEntry[];\n /** Returns metadata for a single controller filtered by its filepath */\n getControllerMetadata(filePath: string): ControllerEntry | undefined;\n /** Gets the raw module entry (with router, middlewares, etc.) */\n getRawModule(name: string): ModuleEntry | undefined;\n /** Registers a file-level identifier (Service, Repository, etc.) in the registry */\n registerFileMetadata(entry: FileEntry): void;\n /** Returns all registered service entries */\n getAllServices(): ServiceEntry[];\n /** Returns a single service entry by name */\n getService(name: string): ServiceEntry | undefined;\n /** Returns all registered repository entries */\n getAllRepositories(): RepositoryEntry[];\n /** Returns a single repository entry by name */\n getRepository(name: string): RepositoryEntry | undefined;\n /** Returns all registered schema entries */\n getAllSchemas(): SchemaEntry[];\n /** Returns a single schema entry by name */\n getSchema(name: string): SchemaEntry | undefined;\n /**\n * @internal for tests only\n */\n clearRegistry(): void;\n}\n\n/**\n * Creates a new independent registry instance.\n * Mainly used to build the singleton, but can be instantiated separately if needed.\n */\nexport function createRegistry(): InternalRegistry {\n const modules = new Map<string, ModuleEntry>();\n const aliases = new Map<string, string>();\n const controllers = new Map<string, ControllerEntry>();\n const services = new Map<string, ServiceEntry>();\n const repositories = new Map<string, RepositoryEntry>();\n const schemas = new Map<string, SchemaEntry>();\n\n return {\n hasModule(name: string): boolean {\n return modules.has(name);\n },\n\n getModule(name: string): RegisteredModule | undefined {\n const entry = modules.get(name);\n return entry ? toRegisteredModule(entry) : undefined;\n },\n\n getAllModules(): RegisteredModule[] {\n return Array.from(modules.values()).map(toRegisteredModule);\n },\n\n resolveAlias(alias: string): string | undefined {\n return aliases.get(alias);\n },\n\n getAllAliases(): Record<string, string> {\n return Object.fromEntries(aliases.entries());\n },\n\n getDependencyGraph(): Map<string, string[]> {\n const graph = new Map<string, string[]>();\n for (const [name, entry] of modules.entries()) {\n graph.set(name, entry.imports);\n }\n return graph;\n },\n\n findCircularDependencies(): string[][] {\n const cycles: string[][] = [];\n const visited = new Set<string>();\n const recStack = new Set<string>();\n const path: string[] = [];\n\n const dfs = (node: string) => {\n visited.add(node);\n recStack.add(node);\n path.push(node);\n\n const deps = modules.get(node)?.imports || [];\n for (const neighbor of deps) {\n if (!visited.has(neighbor)) {\n dfs(neighbor);\n } else if (recStack.has(neighbor)) {\n // We hit a node currently in the stack (cycle detected)\n const cycleStart = path.indexOf(neighbor);\n cycles.push([...path.slice(cycleStart), neighbor]);\n }\n }\n\n recStack.delete(node);\n path.pop();\n };\n\n for (const node of modules.keys()) {\n if (!visited.has(node)) {\n dfs(node);\n }\n }\n\n return cycles;\n },\n\n registerModule(name: string, options: ModuleOptions, dirPath: string, indexPath: string): void {\n if (modules.has(name)) {\n throw new NodulusError(\n 'DUPLICATE_MODULE',\n `A module with this name already exists. Each module must have a unique name.`,\n `Module name: ${name}`\n );\n }\n \n // Check if this directory already has a module registered\n const existing = Array.from(modules.values()).find(m => m.path === dirPath);\n if (existing) {\n throw new NodulusError(\n 'DUPLICATE_MODULE',\n `A module is already registered for this folder. Call Module() only once per directory.`,\n `Existing: ${existing.name}, New: ${name}, Folder: ${dirPath}`\n );\n }\n \n const entry: ModuleEntry = {\n name,\n path: dirPath,\n indexPath,\n imports: options.imports || [],\n exports: options.exports || [],\n controllers: []\n };\n \n modules.set(name, entry);\n },\n\n registerAlias(alias: string, targetPath: string): void {\n const existing = aliases.get(alias);\n if (existing && existing !== targetPath) {\n throw new NodulusError(\n 'DUPLICATE_ALIAS',\n `An alias with this name is already registered to a different target path.`,\n `Alias: ${alias}, Existing: ${existing}, New: ${targetPath}`\n );\n }\n aliases.set(alias, targetPath);\n },\n\n registerControllerMetadata(entry: ControllerEntry): void {\n if (controllers.has(entry.path)) {\n throw new NodulusError(\n 'INVALID_CONTROLLER',\n `Controller() was called more than once in the same file.`,\n `File: ${entry.path}`\n );\n }\n controllers.set(entry.path, entry);\n },\n\n getControllerMetadata(filePath: string): ControllerEntry | undefined {\n return controllers.get(filePath);\n },\n\n getAllControllersMetadata(): ControllerEntry[] {\n return Array.from(controllers.values());\n },\n\n getRawModule(name: string): ModuleEntry | undefined {\n return modules.get(name);\n },\n\n registerFileMetadata(entry: FileEntry): void {\n if (entry.type === 'service') {\n if (services.has(entry.name)) {\n throw new NodulusError(\n 'DUPLICATE_SERVICE',\n `A service named \"${entry.name}\" is already registered. Each Service() name must be unique within the registry.`,\n `Duplicate name: ${entry.name}`\n );\n }\n services.set(entry.name, entry);\n } else if (entry.type === 'repository') {\n if (repositories.has(entry.name)) {\n throw new NodulusError(\n 'DUPLICATE_REPOSITORY',\n `A repository named \"${entry.name}\" is already registered. Each Repository() name must be unique within the registry.`,\n `Duplicate name: ${entry.name}`\n );\n }\n repositories.set(entry.name, entry);\n } else if (entry.type === 'schema') {\n if (schemas.has(entry.name)) {\n throw new NodulusError(\n 'DUPLICATE_SCHEMA',\n `A schema named \"${entry.name}\" is already registered. Each Schema() name must be unique within the registry.`,\n `Duplicate name: ${entry.name}`\n );\n }\n schemas.set(entry.name, entry);\n }\n },\n\n getAllServices(): ServiceEntry[] {\n return Array.from(services.values());\n },\n\n getService(name: string): ServiceEntry | undefined {\n return services.get(name);\n },\n\n getAllRepositories(): RepositoryEntry[] {\n return Array.from(repositories.values());\n },\n\n getRepository(name: string): RepositoryEntry | undefined {\n return repositories.get(name);\n },\n\n getAllSchemas(): SchemaEntry[] {\n return Array.from(schemas.values());\n },\n\n getSchema(name: string): SchemaEntry | undefined {\n return schemas.get(name);\n },\n\n clearRegistry(): void {\n modules.clear();\n aliases.clear();\n controllers.clear();\n services.clear();\n repositories.clear();\n schemas.clear();\n }\n };\n}\n\n/**\n * AsyncLocalStorage context that holds the active registry for the current execution scope.\n * Populated by createApp() — all code running within that scope can retrieve\n * the registry via getActiveRegistry().\n */\nexport const registryContext = new AsyncLocalStorage<InternalRegistry>();\n\n/**\n * Returns the registry bound to the current async execution context.\n * Throws REGISTRY_MISSING_CONTEXT if called outside a createApp() scope.\n * @internal — not exported from index.ts\n */\nexport function getActiveRegistry(): InternalRegistry {\n const store = registryContext.getStore();\n if (!store) {\n throw new NodulusError(\n 'REGISTRY_MISSING_CONTEXT',\n 'No active registry found in the current async context. Ensure code runs inside a createApp() execution scope.'\n );\n }\n return store;\n}\n\n/**\n * Returns a read-only view of the registry active in the current async context.\n * \n * @unstable This function is intended for advanced framework integrations or \n * internal debugging. The structure of the returned registry may change in future \n * minor updates. For standard use cases, rely on the properties returned by `createApp()`.\n */\nexport const getRegistry = (): NodulusRegistryAdvanced => getActiveRegistry();\n","export type NodulusErrorCode =\n | \"MODULE_NOT_FOUND\"\n | \"DUPLICATE_MODULE\"\n | \"MISSING_IMPORT\"\n | \"UNDECLARED_IMPORT\"\n | \"CIRCULAR_DEPENDENCY\"\n | \"EXPORT_MISMATCH\"\n | \"INVALID_CONTROLLER\"\n | \"ALIAS_NOT_FOUND\"\n | \"DUPLICATE_ALIAS\"\n | \"DUPLICATE_BOOTSTRAP\"\n | \"REGISTRY_MISSING_CONTEXT\"\n | \"INVALID_MODULE_DECLARATION\"\n | \"DUPLICATE_SERVICE\"\n | \"DUPLICATE_REPOSITORY\"\n | \"DUPLICATE_SCHEMA\"\n | \"INVALID_ESM_ENV\";\n\nexport class NodulusError extends Error {\n readonly code: NodulusErrorCode;\n readonly details?: string;\n\n constructor(code: NodulusErrorCode, message: string, details?: string) {\n super(message);\n this.name = \"NodulusError\";\n this.code = code;\n this.details = details;\n }\n}\n\n/** @deprecated — not used internally. Messages are defined at each throw site. */\nexport const ERROR_MESSAGES: Record<NodulusErrorCode, string> = {\n MODULE_NOT_FOUND: \"This folder was discovered but index.ts does not call Module(). Add Module('name') to the top of index.ts.\",\n DUPLICATE_MODULE: \"A module with this name or path already exists. Ensure every module name is unique across the app.\",\n MISSING_IMPORT: \"A module listed in 'imports' does not exist in the registry. Verify the module name exists and its index.ts calls Module().\",\n UNDECLARED_IMPORT: \"Attempted to import a module not listed in this module's 'imports' field. Add the missing dependency to Module() options.\",\n CIRCULAR_DEPENDENCY: \"A circular dependency chain was detected. Extract shared logic into a third module to break the cycle.\",\n EXPORT_MISMATCH: \"A name declared in 'exports' is not a real export of index.ts. Ensure you 'export { ... }' the matching member.\",\n INVALID_CONTROLLER: \"Controller has no default export of an Express Router. Add 'export default router;' to the controller file.\",\n ALIAS_NOT_FOUND: \"An alias points to a target directory that does not exist. Verify the path in nodulus.config.ts or createApp() options.\",\n DUPLICATE_ALIAS: \"An alias with this name is already registered to a different path. Check for naming collisions in your config.\",\n DUPLICATE_BOOTSTRAP: \"createApp() was called more than once with the same Express instance. Reuse the existing NodulusApp instead.\",\n REGISTRY_MISSING_CONTEXT: \"No active registry found in the current async context. Ensure Nodulus API calls run within a createApp() scope.\",\n INVALID_MODULE_DECLARATION: \"The Module() call violates architectural rules. Ensure it's called at the top level of index.ts.\",\n DUPLICATE_SERVICE: \"A service with this name is already registered. Ensure every Service() name is unique within the same module.\",\n DUPLICATE_REPOSITORY: \"A repository with this name is already registered. Ensure every Repository() name is unique within the same module.\",\n DUPLICATE_SCHEMA: \"A schema with this name is already registered. Ensure every Schema() name is unique within the same module.\",\n INVALID_ESM_ENV: \"Nodulus requires an ESM environment. Please ensure '\\\"type\\\": \\\"module\\\"' is present heavily in your root package.json file.\",\n};\n","import path from 'node:path';\nimport { getActiveRegistry } from '../core/registry.js';\nimport { NodulusError } from '../core/errors.js';\nimport { getModuleCallerInfo } from '../core/caller.js';\nimport type { ModuleOptions } from '../types/index.js';\n\nexport function Module(name: string, options: ModuleOptions = {}): void {\n if (typeof name !== 'string') {\n throw new TypeError(`Module name must be a string, received ${typeof name}`);\n }\n\n const { filePath: indexPath, dirPath } = getModuleCallerInfo('Module()');\n\n // Rule 1: Name must match folder name\n if (dirPath) {\n const folderName = path.basename(dirPath);\n if (folderName && folderName !== name) {\n throw new NodulusError(\n 'INVALID_MODULE_DECLARATION',\n `Module name \"${name}\" does not match its containing folder \"${folderName}\".`,\n `The module name in Module() MUST match the folder name exactly.`\n );\n }\n }\n\n // Rule 2: Must be called from index file\n const fileName = path.basename(indexPath);\n const isIndexFile = /index\\.(ts|js|mts|mjs)$/.test(fileName);\n if (!isIndexFile) {\n throw new NodulusError(\n 'INVALID_MODULE_DECLARATION',\n `Module() was called from \"${fileName}\", but it must be called only from the module's index file.`,\n `File: ${indexPath}`\n );\n }\n\n getActiveRegistry().registerModule(name, options, dirPath, indexPath);\n}\n","import path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { NodulusError } from '../core/errors.js';\n\n/**\n * Internal utility — NOT part of the public Nodulus API.\n *\n * Walks the V8 call stack to find the file that called one of the Nodulus\n * identifier functions (Module, Service, Controller, Repository, Schema).\n *\n * Stack layout when an identifier function calls this helper:\n * 0 — resolveCallerFile (this function)\n * 1 — Module / Service / … (the identifier)\n * 2 — the user's source file (the caller we want)\n *\n */\nfunction resolveCallerFile(identifierName: string): string {\n const originalFunc = Error.prepareStackTrace;\n let callerFile: string | null = null;\n\n try {\n const err = new Error();\n Error.prepareStackTrace = (_, stack) => stack;\n const stack = err.stack as unknown as NodeJS.CallSite[];\n // Depth: 0 is resolveCallerFile, 1 is getCallerFileAndDir/getCallerFilePath, 2 is the identifier (Module, Service), 3 is the user's file\n if (stack && stack.length > 3) {\n callerFile = stack[3].getFileName() || null;\n }\n } catch {\n // getFileName() is unavailable in this environment;\n // the null-check below will throw a descriptive NodulusError.\n } finally {\n Error.prepareStackTrace = originalFunc;\n }\n\n if (!callerFile) {\n throw new NodulusError(\n 'INVALID_MODULE_DECLARATION',\n `${identifierName} could not determine caller path. Stack trace unavailable.`,\n 'Ensure you are using Node.js >= 20.6 with ESM and no bundler obfuscation.'\n );\n }\n\n // Normalise ESM file:// URLs to OS-native paths\n if (callerFile.startsWith('file://')) {\n callerFile = fileURLToPath(callerFile);\n }\n\n return callerFile;\n}\n\n/**\n * Returns the caller's file path and its containing directory.\n * Used by `Module()`, which needs both pieces to enforce naming rules.\n */\nexport function getModuleCallerInfo(\n identifierName: string\n): { filePath: string; dirPath: string } {\n const filePath = resolveCallerFile(identifierName);\n return { filePath, dirPath: path.dirname(filePath) };\n}\n\n/**\n * Returns only the caller's absolute file path.\n * Used by all non-Module identifiers (Service, Controller, Repository, Schema).\n */\nexport function getFileCallerInfo(\n identifierName: string\n): { filePath: string } {\n return { filePath: resolveCallerFile(identifierName) };\n}\n","import path from 'node:path';\nimport { getActiveRegistry } from '../core/registry.js';\nimport { getFileCallerInfo } from '../core/caller.js';\nimport type { ControllerOptions } from '../types/index.js';\n\nexport function Controller(prefix: string, options: ControllerOptions = {}): void {\n if (typeof prefix !== 'string') {\n throw new TypeError(`Controller prefix must be a string, received ${typeof prefix}`);\n }\n\n const { filePath } = getFileCallerInfo('Controller()');\n const name = path.parse(filePath).name;\n\n getActiveRegistry().registerControllerMetadata({\n name,\n path: filePath,\n prefix: prefix,\n middlewares: options.middlewares ?? [],\n enabled: options.enabled ?? true\n });\n}\n","import path from 'node:path';\nimport { getActiveRegistry } from '../core/registry.js';\nimport { getFileCallerInfo } from '../core/caller.js';\nimport type { ServiceOptions } from '../types/index.js';\n\n/**\n * Declares a file as a named service and registers it in the Nodulus registry.\n *\n * The `module` field is inferred from the parent folder name when not provided explicitly.\n *\n * @param name - Unique service name within the registry (e.g. 'UserService').\n * @param options - Optional configuration: module override and description.\n *\n * @example\n * // src/modules/users/users.service.ts\n * import { Service } from 'nodulus'\n *\n * Service('UserService', { module: 'users' })\n *\n * export const UserService = { ... }\n */\nexport function Service(name: string, options: ServiceOptions = {}): void {\n if (typeof name !== 'string' || name.trim() === '') {\n throw new TypeError(`Service name must be a non-empty string, received ${typeof name}`);\n }\n\n const { filePath } = getFileCallerInfo('Service()');\n\n // Infer module from the parent folder name if not explicitly provided\n const inferredModule = options.module ?? path.basename(path.dirname(filePath));\n\n getActiveRegistry().registerFileMetadata({\n name,\n path: filePath,\n type: 'service',\n module: inferredModule,\n description: options.description,\n });\n}\n","import path from 'node:path';\nimport { getActiveRegistry } from '../core/registry.js';\nimport { getFileCallerInfo } from '../core/caller.js';\nimport type { RepositoryOptions } from '../types/index.js';\n\n/**\n * Declares a file as a named repository and registers it in the Nodulus registry.\n *\n * The `module` field is inferred from the parent folder name when not provided explicitly.\n *\n * @param name - Unique repository name within the registry (e.g. 'UserRepository').\n * @param options - Optional configuration: module override, description, and data source type.\n *\n * @example\n * // src/modules/users/users.repository.ts\n * import { Repository } from 'nodulus'\n *\n * Repository('UserRepository', { module: 'users', source: 'database' })\n *\n * export const UserRepository = { ... }\n */\nexport function Repository(name: string, options: RepositoryOptions = {}): void {\n if (typeof name !== 'string' || name.trim() === '') {\n throw new TypeError(`Repository name must be a non-empty string, received ${typeof name}`);\n }\n\n const { filePath } = getFileCallerInfo('Repository()');\n\n // Infer module from the parent folder name if not explicitly provided\n const inferredModule = options.module ?? path.basename(path.dirname(filePath));\n\n getActiveRegistry().registerFileMetadata({\n name,\n path: filePath,\n type: 'repository',\n module: inferredModule,\n description: options.description,\n source: options.source,\n });\n}\n","import path from 'node:path';\nimport { getActiveRegistry } from '../core/registry.js';\nimport { getFileCallerInfo } from '../core/caller.js';\nimport type { SchemaOptions } from '../types/index.js';\n\n/**\n * Declares a file as a named validation schema and registers it in the Nodulus registry.\n *\n * The `module` field is inferred from the parent folder name when not provided explicitly.\n *\n * @param name - Unique schema name within the registry (e.g. 'CreateUserSchema').\n * @param options - Optional configuration: module override, description, and validation library.\n *\n * @example\n * // src/modules/users/users.schema.ts\n * import { Schema } from 'nodulus'\n *\n * Schema('CreateUserSchema', { module: 'users', library: 'zod' })\n *\n * export const CreateUserSchema = z.object({ ... })\n */\nexport function Schema(name: string, options: SchemaOptions = {}): void {\n if (typeof name !== 'string' || name.trim() === '') {\n throw new TypeError(`Schema name must be a non-empty string, received ${typeof name}`);\n }\n\n const { filePath } = getFileCallerInfo('Schema()');\n\n // Infer module from the parent folder name if not explicitly provided\n const inferredModule = options.module ?? path.basename(path.dirname(filePath));\n\n getActiveRegistry().registerFileMetadata({\n name,\n path: filePath,\n type: 'schema',\n module: inferredModule,\n description: options.description,\n library: options.library,\n });\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport fg from 'fast-glob';\nimport type { Application } from 'express';\nimport type { CreateAppOptions, NodulusApp } from '../types/index.js';\nimport { loadConfig } from '../core/config.js';\nimport { NodulusError } from '../core/errors.js';\nimport { createRegistry, registryContext } from '../core/registry.js';\nimport { activateAliasResolver } from '../aliases/resolver.js';\nimport { updateAliasCache } from '../aliases/cache.js';\nimport { createLogger } from '../core/logger.js';\nimport { performance } from 'node:perf_hooks';\nimport pc from 'picocolors';\n\nexport async function createApp(\n app: Application,\n options: CreateAppOptions = {}\n): Promise<NodulusApp> {\n // Step 0 — Prevent Duplicate Bootstrap\n if ((app as any).__nodulusBootstrapped) {\n throw new NodulusError(\n 'DUPLICATE_BOOTSTRAP',\n 'createApp() was called more than once with the same Express instance.'\n );\n }\n\n // Step 0.5 — ESM Environment Validation\n let isEsm = false;\n try {\n const pkgPath = path.resolve(process.cwd(), 'package.json');\n if (fs.existsSync(pkgPath)) {\n const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));\n if (pkg.type === 'module') {\n isEsm = true;\n }\n }\n } catch (_e) {\n // Failsafe, could not parse package.json, assume non-ESM to fail securely\n }\n\n if (!isEsm) {\n throw new NodulusError(\n 'INVALID_ESM_ENV',\n 'Nodulus requires an ESM environment. Please ensure \"type\": \"module\" is present in your root package.json file.'\n );\n }\n\n const registry = createRegistry();\n\n return registryContext.run(registry, async () => {\n const startTime = performance.now();\n try {\n\n // Step 1 — Load configuration\n const config = await loadConfig(options);\n const log = createLogger(config.logger, config.logLevel);\n\n log.info('Bootstrap started', {\n modules: pc.cyan(config.modules),\n prefix: pc.cyan(config.prefix || '(none)'),\n strict: pc.yellow(String(config.strict)),\n nodeVersion: pc.gray(process.version),\n });\n\n // Step 2 — Resolve modules\n const globPattern = config.modules.replace(/\\\\/g, '/');\n const moduleDirs = await fg(globPattern, {\n onlyDirectories: true,\n absolute: true,\n cwd: process.cwd()\n });\n\n // Ensure strict alphabetical ordering\n moduleDirs.sort();\n\n // Store useful resolved paths for the upcoming steps\n const resolvedModules: { dirPath: string, indexPath: string }[] = [];\n\n for (const dirPath of moduleDirs) {\n log.debug(`Discovered module directory: ${dirPath}`, { dirPath });\n const tsPath = path.join(dirPath, 'index.ts');\n const jsPath = path.join(dirPath, 'index.js');\n \n let indexPath: string | null = null;\n \n if (fs.existsSync(tsPath)) {\n indexPath = tsPath;\n } else if (fs.existsSync(jsPath)) {\n indexPath = jsPath;\n }\n\n if (!indexPath) {\n throw new NodulusError(\n 'MODULE_NOT_FOUND',\n `No index.ts or index.js found for module. A module directory must have an index file mapping its dependencies.`,\n `Directory: ${dirPath}`\n );\n }\n \n resolvedModules.push({ dirPath, indexPath });\n }\n\n // Step 3 — Activate runtime aliases\n // Using pureModuleAliases to separate user configured folders vs magically generated modules\n if (config.resolveAliases !== false) {\n const pureModuleAliases: Record<string, string> = {};\n \n // Automatically resolve @modules/<name> for each module\n for (const mod of resolvedModules) {\n const modName = path.basename(mod.dirPath);\n const aliasKey = `@modules/${modName}`;\n pureModuleAliases[aliasKey] = mod.dirPath;\n registry.registerAlias(aliasKey, mod.dirPath);\n }\n\n activateAliasResolver(pureModuleAliases, config.aliases, log);\n updateAliasCache(registry.getAllAliases());\n }\n\n // Step 4 — Import modules\n for (const mod of resolvedModules) {\n const imported = await import(pathToFileURL(mod.indexPath).href);\n\n // Correlate the imported module with the one added to the registry based on dirPath\n const allRegistered = registry.getAllModules();\n const registeredMod = allRegistered.find(m => path.normalize(m.path) === path.normalize(mod.dirPath));\n\n if (!registeredMod) {\n throw new NodulusError(\n 'MODULE_NOT_FOUND',\n `No index.ts found calling Module(). Add Module() to the module's index.ts.`,\n `File: ${mod.indexPath}`\n );\n }\n\n log.info(`Module loaded: ${pc.green(registeredMod.name)}`, {\n name: registeredMod.name,\n imports: registeredMod.imports,\n exports: registeredMod.exports,\n path: registeredMod.path,\n });\n\n // Validate Exports\n // CJS/ESM behavior: on dynamic imports, named exports are mapped as object keys.\n const actualExports = Object.keys(imported).filter(key => key !== 'default');\n const declaredExports = registeredMod.exports || [];\n\n for (const declared of declaredExports) {\n if (!actualExports.includes(declared)) {\n throw new NodulusError(\n 'EXPORT_MISMATCH',\n `A name declared in exports does not exist as a real export of index.ts.`,\n `Module: ${registeredMod.name}, Missing Export: ${declared}`\n );\n }\n }\n\n if (config.strict) {\n for (const actual of actualExports) {\n if (!declaredExports.includes(actual)) {\n log.warn(\n `Module \"${registeredMod.name}\" exports \"${actual}\" but it is not declared in Module() options \"exports\" array.`,\n { name: registeredMod.name, exportName: actual }\n );\n }\n }\n }\n }\n\n // Step 5 — Validate dependencies\n const allModules = registry.getAllModules();\n for (const mod of allModules) {\n for (const importName of mod.imports) {\n if (!registry.hasModule(importName)) {\n throw new NodulusError(\n 'MISSING_IMPORT',\n `A module declared in imports does not exist in the registry.`,\n `Module \"${mod.name}\" is trying to import missing module \"${importName}\"`\n );\n }\n }\n }\n\n // Strict mode validations for circular dependencies\n if (config.strict) {\n const cycles = registry.findCircularDependencies();\n if (cycles.length > 0) {\n const cycleStrings = cycles.map(cycle => cycle.join(' -> ')).join(' | ');\n throw new NodulusError(\n 'CIRCULAR_DEPENDENCY',\n `Circular dependency detected. Extract the shared dependency into a separate module.`,\n `Cycles found: ${cycleStrings}`\n );\n }\n }\n\n // Step 6 — Discover controllers\n for (const mod of allModules) {\n const rawMod = registry.getRawModule(mod.name);\n if (!rawMod) continue; // Failsafe, should always exist\n\n const files = await fg('**/*.{ts,js,mts,mjs,cjs}', {\n cwd: mod.path,\n absolute: true,\n ignore: [\n '**/*.types.*',\n '**/*.d.ts',\n '**/*.spec.*',\n '**/*.test.*',\n 'index.*' // Escapes root index.ts/js\n ]\n });\n\n files.sort();\n\n for (let file of files) {\n log.debug(`Scanning controller file: ${file}`, { filePath: file, module: mod.name });\n file = path.normalize(file);\n let imported: any;\n try {\n imported = await import(pathToFileURL(file).href);\n } catch (err: any) {\n throw new NodulusError(\n 'INVALID_CONTROLLER',\n `Failed to import controller file. Check for syntax errors or missing dependencies.`,\n `File: ${file} — ${err.message}`\n );\n }\n\n const resolvedFile = path.normalize(file);\n const ctrlMeta = registry.getControllerMetadata(resolvedFile) || registry.getAllControllersMetadata().find(c => path.normalize(c.path) === resolvedFile);\n if (ctrlMeta) {\n // Evaluate router validity (must be default export & resemble an Express router)\n const isRouter = imported.default && typeof imported.default === 'function' && typeof imported.default.use === 'function';\n \n if (!isRouter) {\n throw new NodulusError(\n 'INVALID_CONTROLLER',\n `Controller has no default export of a Router. Add export default router.`,\n `File: ${file}`\n );\n }\n\n log.debug(`Controller registered: ${pc.green(ctrlMeta.name)} → ${pc.cyan(ctrlMeta.prefix)}`, {\n name: ctrlMeta.name,\n prefix: ctrlMeta.prefix,\n module: mod.name,\n middlewareCount: ctrlMeta.middlewares.length,\n });\n\n // Bind the active Express Router instance directly to the internally saved metadata\n ctrlMeta.router = imported.default;\n rawMod.controllers.push(ctrlMeta);\n }\n }\n\n if (rawMod.controllers.length === 0) {\n log.warn(`Module \"${mod.name}\" has no controllers — no routes will be mounted from it`, {\n name: mod.name,\n path: mod.path,\n });\n }\n }\n\n // Step 7 — Mount routes\n const mountedRoutes: import('../types/index.js').MountedRoute[] = [];\n\n for (const mod of allModules) {\n const rawMod = registry.getRawModule(mod.name);\n if (!rawMod) continue;\n\n for (const ctrl of rawMod.controllers) {\n if (!ctrl.enabled) {\n log.info(`Controller \"${ctrl.name}\" is disabled — skipping mount`, {\n name: ctrl.name,\n module: mod.name,\n prefix: ctrl.prefix,\n });\n continue;\n }\n\n const fullPath = (config.prefix + ctrl.prefix).replace(/\\/+/g, '/').replace(/\\/$/, '') || '/';\n\n if (ctrl.router) {\n\n if (ctrl.middlewares && ctrl.middlewares.length > 0) {\n app.use(fullPath, ...ctrl.middlewares, ctrl.router);\n } else {\n app.use(fullPath, ctrl.router);\n }\n\n // Try to extract individual routes from Express router stack\n // If impossible, fallback to USE basepath.\n let foundRoutes = false;\n const extractedRoutes: { method: string, path: string }[] = [];\n\n if (ctrl.router.stack && Array.isArray(ctrl.router.stack)) {\n for (const layer of ctrl.router.stack) {\n const routeObj = layer.route as any;\n if (routeObj && routeObj.methods) {\n foundRoutes = true;\n const routePath = routeObj.path;\n const methods = Object.keys(routeObj.methods).filter(m => routeObj.methods[m]).map(m => m.toUpperCase());\n \n for (const method of methods) {\n const fullRoutePath = (fullPath + (routePath === '/' ? '' : routePath)).replace(/\\/+/g, '/');\n extractedRoutes.push({ method, path: fullRoutePath });\n mountedRoutes.push({\n method: method as any,\n path: fullRoutePath,\n module: mod.name,\n controller: ctrl.name\n });\n }\n }\n }\n }\n\n if (!foundRoutes) {\n extractedRoutes.push({ method: 'USE', path: fullPath });\n mountedRoutes.push({\n method: 'USE',\n path: fullPath,\n module: mod.name,\n controller: ctrl.name\n });\n }\n\n const methodColors: Record<string, (msg: string) => string> = {\n GET: pc.green,\n POST: pc.yellow,\n PUT: pc.cyan,\n PATCH: pc.magenta,\n DELETE: pc.red,\n USE: pc.gray,\n };\n\n for (const route of extractedRoutes) {\n const colorFn = methodColors[route.method] || pc.white;\n log.info(` ${colorFn(route.method.padEnd(6))} ${pc.white(route.path)} ${pc.gray(`(${ctrl.name})`)}`, {\n method: route.method,\n path: route.path,\n module: mod.name,\n controller: ctrl.name,\n });\n }\n }\n }\n }\n\n // Tag Express app to prevent double boot\n (app as any).__nodulusBootstrapped = true;\n\n // Step 8 — Return NodulusApp\n const safeRegisteredModules = allModules.map(m => registry.getModule(m.name)!);\n \n const durationMs = Math.round(performance.now() - startTime);\n log.info(`${pc.green('Bootstrap complete')} — ${pc.cyan(allModules.length)} module(s), ${pc.cyan(mountedRoutes.length)} route(s) in ${pc.yellow(`${durationMs}ms`)}`, {\n moduleCount: allModules.length,\n routeCount: mountedRoutes.length,\n durationMs,\n });\n\n return {\n modules: safeRegisteredModules,\n routes: mountedRoutes,\n registry\n };\n\n } catch (err) {\n // Rollback: discard any partially registered state so a retry\n // does not encounter leftover modules or aliases.\n registry.clearRegistry();\n throw err;\n }\n });\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport type { CreateAppOptions, ResolvedConfig, NodulusConfig } from '../types/index.js';\nimport { defaultLogHandler, resolveLogLevel } from './logger.js';\n\nconst defaultStrict = typeof process !== 'undefined' && process.env?.NODE_ENV !== 'production';\n\nexport const DEFAULTS: ResolvedConfig = {\n modules: 'src/modules/*',\n prefix: '',\n aliases: {},\n strict: defaultStrict,\n resolveAliases: true,\n logger: defaultLogHandler,\n logLevel: resolveLogLevel(),\n};\n\nexport const loadConfig = async (options: CreateAppOptions = {}): Promise<ResolvedConfig> => {\n const cwd = process.cwd();\n \n let fileConfig: NodulusConfig = {};\n \n const tsPath = path.join(cwd, 'nodulus.config.ts');\n const jsPath = path.join(cwd, 'nodulus.config.js');\n \n const isProduction = process.env.NODE_ENV === 'production';\n const hasTsLoader = \n process.execArgv.some(arg => arg.includes('ts-node') || arg.includes('tsx')) ||\n (process as any)._preload_modules?.some((m: string) => m.includes('ts-node') || m.includes('tsx'));\n\n // In production, only .js is tried by default.\n // In development (or when a TS loader is detected), .ts is tried first.\n const candidates: string[] = [];\n \n if (!isProduction || hasTsLoader) {\n candidates.push(tsPath);\n }\n candidates.push(jsPath);\n\n let configPathToLoad: string | null = null;\n\n for (const candidate of candidates) {\n if (fs.existsSync(candidate)) {\n configPathToLoad = candidate;\n break;\n }\n }\n\n if (configPathToLoad) {\n try {\n const importUrl = pathToFileURL(configPathToLoad).href;\n const mod = await import(importUrl);\n fileConfig = mod.default || mod.config || mod;\n } catch (error: any) {\n if (configPathToLoad.endsWith('.ts') && error.code === 'ERR_UNKNOWN_FILE_EXTENSION') {\n throw new Error(\n `[Nodulus] Found \"nodulus.config.ts\" but your environment cannot load raw TypeScript files.\\n` +\n ` - In production: Run \"npm run build\" to generate a .js config OR use nodulus.config.js.\\n` +\n ` - In development: Ensure you are running with a loader like \"tsx\" or \"ts-node\".`,\n { cause: error }\n );\n }\n throw new Error(`[Nodulus] Failed to parse or evaluate config file at ${configPathToLoad}: ${error.message}`, { cause: error });\n }\n }\n\n // Merge strategy: options > fileConfig > defaults\n return {\n modules: options.modules ?? fileConfig.modules ?? DEFAULTS.modules,\n prefix: options.prefix ?? fileConfig.prefix ?? DEFAULTS.prefix,\n aliases: {\n ...DEFAULTS.aliases,\n ...(fileConfig.aliases || {}),\n ...(options.aliases || {}) // Options override file aliases\n },\n strict: options.strict ?? fileConfig.strict ?? DEFAULTS.strict,\n resolveAliases: options.resolveAliases ?? fileConfig.resolveAliases ?? DEFAULTS.resolveAliases,\n logger: options.logger ?? fileConfig.logger ?? DEFAULTS.logger,\n logLevel: resolveLogLevel(options.logLevel ?? fileConfig.logLevel),\n };\n};\n","import pc from 'picocolors';\nimport type { LogLevel, LogHandler } from '../types/index.js';\n\nconst LEVEL_ORDER: Record<LogLevel, number> = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n};\n\nconst LEVEL_STYLE: Record<LogLevel, (msg: string) => string> = {\n debug: (msg) => pc.gray(msg),\n info: (msg) => pc.cyan(msg),\n warn: (msg) => pc.yellow(msg),\n error: (msg) => pc.red(msg),\n};\n\nconst LEVEL_LABELS: Record<LogLevel, string> = {\n debug: 'debug',\n info: 'info ', // trailing space for alignment\n warn: 'warn ',\n error: 'error',\n};\n\n/**\n * Default log handler. Writes to process.stdout (info/debug) or process.stderr (warn/error).\n * All lines are prefixed with [Nodulus].\n */\nexport const defaultLogHandler: LogHandler = (level, message) => {\n const prefix = pc.gray('[Nodulus]');\n const label = LEVEL_STYLE[level](LEVEL_LABELS[level]);\n const line = `${prefix} ${label} ${message}`;\n \n if (level === 'warn' || level === 'error') {\n process.stderr.write(line + '\\n');\n } else {\n process.stdout.write(line + '\\n');\n }\n};\n\n/**\n * Resolves the effective minimum log level.\n * Priority: explicit logLevel option > NODE_DEBUG env var > default ('info').\n */\nexport function resolveLogLevel(explicit?: LogLevel): LogLevel {\n if (explicit) return explicit;\n\n const nodeDebug = process.env.NODE_DEBUG ?? '';\n if (nodeDebug.split(',').map(s => s.trim()).includes('nodulus')) {\n return 'debug';\n }\n\n return 'info';\n}\n\nexport interface Logger {\n debug(message: string, meta?: Record<string, unknown>): void;\n info(message: string, meta?: Record<string, unknown>): void;\n warn(message: string, meta?: Record<string, unknown>): void;\n error(message: string, meta?: Record<string, unknown>): void;\n}\n\n/**\n * Creates a bound logger that filters by minLevel and delegates to handler.\n * \n * @param handler - Where log events are sent.\n * @param minLevel - Events below this level are discarded.\n */\nexport function createLogger(handler: LogHandler, minLevel: LogLevel): Logger {\n const minOrder = LEVEL_ORDER[minLevel];\n\n const emit = (level: LogLevel, message: string, meta?: Record<string, unknown>) => {\n if (LEVEL_ORDER[level] >= minOrder) {\n handler(level, message, meta);\n }\n };\n\n return {\n debug: (msg, meta) => emit('debug', msg, meta),\n info: (msg, meta) => emit('info', msg, meta),\n warn: (msg, meta) => emit('warn', msg, meta),\n error: (msg, meta) => emit('error', msg, meta),\n };\n}\n","import { register } from 'node:module';\nimport { pathToFileURL } from 'node:url';\nimport type { Logger } from '../core/logger.js';\n\n// Node.js Customization Hooks types\nexport type ResolveHookContext = {\n conditions: string[];\n parentURL?: string;\n data?: any;\n};\n\nexport type NextResolve = (specifier: string, context?: ResolveHookContext) => Promise<{ shortCircuit?: boolean; url: string }>;\n\nexport type ResolveHook = (\n specifier: string,\n context: ResolveHookContext,\n nextResolve: NextResolve\n) => Promise<{ shortCircuit?: boolean; url: string }>;\n\nlet isHookRegistered = false;\n\n/** @internal exclusively for tests */\nexport function clearAliasResolverOptions(): void {\n isHookRegistered = false;\n}\n\n/**\n * Activates the ESM Alias Resolver using Node.js module.register.\n * \n * Limitation: This ESM hook is strictly for Node ESM pipelines (Node >= 20.6.0).\n * It will not function effectively in pure CJS pipelines without a transpiler or loader.\n * For CJS and bundlers (Vite, esbuild), use getAliases() to configure their specific resolvers.\n */\nexport function activateAliasResolver(moduleAliases: Record<string, string>, folderAliases: Record<string, string>, log: Logger): void {\n if (isHookRegistered) return;\n \n const combinedAliases = { ...moduleAliases, ...folderAliases };\n\n for (const [alias, target] of Object.entries(folderAliases)) {\n log.debug(`Alias registered: ${alias} → ${target}`, { alias, target, source: 'config' });\n }\n for (const [alias, target] of Object.entries(moduleAliases)) {\n log.debug(`Alias registered: ${alias} → ${target}`, { alias, target, source: 'module' });\n }\n\n // Aliases are serialised directly into the hook source so they are available\n // in the hook's closure regardless of whether Node.js propagates context.data\n // across all resolution chains (not guaranteed in every Node 20.6+ build).\n const serialisedAliases = JSON.stringify(combinedAliases);\n\n const loaderCode = `\nimport { pathToFileURL } from 'node:url';\nimport path from 'node:path';\n\nconst aliases = ${serialisedAliases};\n\nexport async function resolve(specifier, context, nextResolve) {\n for (const alias of Object.keys(aliases)) {\n if (specifier === alias || specifier.startsWith(alias + '/')) {\n const target = aliases[alias];\n const resolvedPath = specifier.replace(alias, target);\n return nextResolve(pathToFileURL(path.resolve(resolvedPath)).href, context);\n }\n }\n return nextResolve(specifier, context);\n}\n`;\n\n try {\n const dataUrl = `data:text/javascript,${encodeURIComponent(loaderCode)}`;\n const parentUrl = typeof __filename === 'undefined' ? import.meta.url : pathToFileURL(__filename).href;\n \n if (typeof register === 'function') {\n register(dataUrl, { parentURL: parentUrl });\n isHookRegistered = true;\n log.info(`ESM alias hook activated (${Object.keys(combinedAliases).length} alias(es))`, {\n aliasCount: Object.keys(combinedAliases).length\n });\n } else {\n log.warn('ESM alias hook could not be registered — upgrade to Node.js >= 20.6.0 for runtime alias support', {\n nodeVersion: process.version\n });\n }\n } catch (err) {\n log.warn('ESM alias hook registration threw an unexpected error — aliases may not resolve at runtime', {\n error: (err as any)?.message ?? String(err)\n });\n }\n}\n","// Limitation: last write wins in parallel tests.\n// Do not use getAliasCache() in concurrent tests that rely on different aliases.\nlet aliasCache: Record<string, string> = {};\n\nexport function updateAliasCache(aliases: Record<string, string>): void {\n aliasCache = { ...aliases };\n}\n\nexport function getAliasCache(): Record<string, string> {\n return aliasCache;\n}\n\nexport function clearAliasCache(): void {\n aliasCache = {};\n}\n","import path from 'node:path';\nimport { getAliasCache } from './cache.js';\nimport type { GetAliasesOptions } from '../types/index.js';\n\nexport async function getAliases(options: GetAliasesOptions = {}): Promise<Record<string, string>> {\n const includeFolders = options.includeFolders ?? true;\n const absolute = options.absolute ?? false;\n\n const allAliases = getAliasCache();\n const result: Record<string, string> = {};\n const cwd = process.cwd();\n \n for (const [alias, target] of Object.entries(allAliases)) {\n if (!includeFolders && !alias.startsWith('@modules/')) {\n continue;\n }\n \n let resolvedPath: string;\n \n if (absolute) {\n resolvedPath = path.isAbsolute(target) ? target : path.resolve(cwd, target);\n // Extra step if it's a @modules to point to index specifically (optional, but often useful for bundlers resolving dynamic exports)\n // Actually, we maintain exactly what is stored!\n } else {\n resolvedPath = path.isAbsolute(target) ? path.relative(cwd, target) : target;\n \n // Ensure positive POSIX formatting for bundlers\n resolvedPath = resolvedPath.replace(/\\\\/g, '/');\n if (!resolvedPath.startsWith('.') && !resolvedPath.startsWith('/')) {\n resolvedPath = './' + resolvedPath;\n }\n }\n \n result[alias] = resolvedPath;\n }\n \n return result;\n}\n"],"mappings":"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","names":["path","path","stack","path","path","path","path","path","path","path","path","path","fs","path","pathToFileURL","path","path","pathToFileURL","pathToFileURL","pc","path","fs","pathToFileURL","path","path"]}
|
|
1
|
+
{"version":3,"sources":["../src/core/registry.ts","../src/core/errors.ts","../src/core/utils/cycle-detector.ts","../src/identifiers/module.ts","../src/core/caller.ts","../src/identifiers/controller.ts","../src/identifiers/service.ts","../src/identifiers/repository.ts","../src/identifiers/schema.ts","../src/bootstrap/createApp.ts","../src/core/config.ts","../src/core/logger.ts","../src/aliases/resolver.ts","../src/aliases/cache.ts","../src/aliases/getAliases.ts"],"sourcesContent":["import { AsyncLocalStorage } from 'node:async_hooks';\nimport { NodulusError } from './errors.js';\nimport { findCircularDependencies } from './utils/cycle-detector.js';\nimport type { \n ModuleEntry, \n RegisteredModule, \n NodulusRegistryAdvanced,\n ModuleOptions,\n ControllerEntry,\n ServiceEntry,\n RepositoryEntry,\n SchemaEntry,\n FileEntry\n} from '../types/index.js';\n\nexport type ModuleRegistration = RegisteredModule;\nexport type FeatureRegistration = FileEntry;\n\nconst toRegisteredModule = (entry: ModuleEntry): RegisteredModule => ({\n name: entry.name,\n path: entry.path,\n imports: entry.imports,\n exports: entry.exports,\n controllers: entry.controllers.map(c => c.name)\n});\n\n/** \n * Extended interface for internal use (includes mutators)\n * @internal\n */\nexport interface InternalRegistry extends NodulusRegistryAdvanced {\n /** Registers an internal module and throws DUPLICATE_MODULE if it already exists */\n registerModule(name: string, options: ModuleOptions, dirPath: string, indexPath: string): void;\n /** Adds an alias to the registry */\n registerAlias(alias: string, path: string): void;\n /** Stores temporary metadata for a recently evaluated controller */\n registerControllerMetadata(entry: ControllerEntry): void;\n /** Returns metadata for all controllers (useful for tests and bootstrap) */\n getAllControllersMetadata(): ControllerEntry[];\n /** Returns metadata for a single controller filtered by its filepath */\n getControllerMetadata(filePath: string): ControllerEntry | undefined;\n /** Gets the raw module entry (with router, middlewares, etc.) */\n getRawModule(name: string): ModuleEntry | undefined;\n /** Registers a file-level identifier (Service, Repository, etc.) in the registry */\n registerFileMetadata(entry: FileEntry): void;\n /** Returns all registered service entries */\n getAllServices(): ServiceEntry[];\n /** Returns a single service entry by name */\n getService(name: string): ServiceEntry | undefined;\n /** Returns all registered repository entries */\n getAllRepositories(): RepositoryEntry[];\n /** Returns a single repository entry by name */\n getRepository(name: string): RepositoryEntry | undefined;\n /** Returns all registered schema entries */\n getAllSchemas(): SchemaEntry[];\n /** Returns a single schema entry by name */\n getSchema(name: string): SchemaEntry | undefined;\n /**\n * @internal for tests only\n */\n clearRegistry(): void;\n}\n\n/**\n * Creates a new independent registry instance.\n * Mainly used to build the singleton, but can be instantiated separately if needed.\n * @internal\n */\nexport function createRegistry(): InternalRegistry {\n const modules = new Map<string, ModuleEntry>();\n const aliases = new Map<string, string>();\n const controllers = new Map<string, ControllerEntry>();\n const services = new Map<string, ServiceEntry>();\n const repositories = new Map<string, RepositoryEntry>();\n const schemas = new Map<string, SchemaEntry>();\n\n return {\n hasModule(name: string): boolean {\n return modules.has(name);\n },\n\n getModule(name: string): RegisteredModule | undefined {\n const entry = modules.get(name);\n return entry ? toRegisteredModule(entry) : undefined;\n },\n\n getAllModules(): RegisteredModule[] {\n return Array.from(modules.values()).map(toRegisteredModule);\n },\n\n resolveAlias(alias: string): string | undefined {\n return aliases.get(alias);\n },\n\n getAllAliases(): Record<string, string> {\n return Object.fromEntries(aliases.entries());\n },\n\n getDependencyGraph(): Map<string, string[]> {\n const graph = new Map<string, string[]>();\n for (const [name, entry] of modules.entries()) {\n graph.set(name, entry.imports);\n }\n return graph;\n },\n\n findCircularDependencies(): string[][] {\n const dependencyMap = new Map<string, string[]>();\n for (const [name, entry] of modules.entries()) {\n dependencyMap.set(name, entry.imports);\n }\n return findCircularDependencies(dependencyMap);\n },\n\n registerModule(name: string, options: ModuleOptions, dirPath: string, indexPath: string): void {\n if (modules.has(name)) {\n throw new NodulusError(\n 'DUPLICATE_MODULE',\n `A module with this name already exists. Each module must have a unique name.`,\n `Module name: ${name}`\n );\n }\n \n // Check if this directory already has a module registered\n const existing = Array.from(modules.values()).find(m => m.path === dirPath);\n if (existing) {\n throw new NodulusError(\n 'DUPLICATE_MODULE',\n `A module is already registered for this folder. Call Module() only once per directory.`,\n `Existing: ${existing.name}, New: ${name}, Folder: ${dirPath}`\n );\n }\n \n const entry: ModuleEntry = {\n name,\n path: dirPath,\n indexPath,\n imports: options.imports || [],\n exports: options.exports || [],\n controllers: []\n };\n \n modules.set(name, entry);\n },\n\n registerAlias(alias: string, targetPath: string): void {\n const existing = aliases.get(alias);\n if (existing && existing !== targetPath) {\n throw new NodulusError(\n 'DUPLICATE_ALIAS',\n `An alias with this name is already registered to a different target path.`,\n `Alias: ${alias}, Existing: ${existing}, New: ${targetPath}`\n );\n }\n aliases.set(alias, targetPath);\n },\n\n registerControllerMetadata(entry: ControllerEntry): void {\n if (controllers.has(entry.path)) {\n throw new NodulusError(\n 'INVALID_CONTROLLER',\n `Controller() was called more than once in the same file.`,\n `File: ${entry.path}`\n );\n }\n controllers.set(entry.path, entry);\n },\n\n getControllerMetadata(filePath: string): ControllerEntry | undefined {\n return controllers.get(filePath);\n },\n\n getAllControllersMetadata(): ControllerEntry[] {\n return Array.from(controllers.values());\n },\n\n getRawModule(name: string): ModuleEntry | undefined {\n return modules.get(name);\n },\n\n registerFileMetadata(entry: FileEntry): void {\n if (entry.type === 'service') {\n if (services.has(entry.name)) {\n throw new NodulusError(\n 'DUPLICATE_SERVICE',\n `A service named \"${entry.name}\" is already registered. Each Service() name must be unique within the registry.`,\n `Duplicate name: ${entry.name}`\n );\n }\n services.set(entry.name, entry);\n } else if (entry.type === 'repository') {\n if (repositories.has(entry.name)) {\n throw new NodulusError(\n 'DUPLICATE_REPOSITORY',\n `A repository named \"${entry.name}\" is already registered. Each Repository() name must be unique within the registry.`,\n `Duplicate name: ${entry.name}`\n );\n }\n repositories.set(entry.name, entry);\n } else if (entry.type === 'schema') {\n if (schemas.has(entry.name)) {\n throw new NodulusError(\n 'DUPLICATE_SCHEMA',\n `A schema named \"${entry.name}\" is already registered. Each Schema() name must be unique within the registry.`,\n `Duplicate name: ${entry.name}`\n );\n }\n schemas.set(entry.name, entry);\n }\n },\n\n getAllServices(): ServiceEntry[] {\n return Array.from(services.values());\n },\n\n getService(name: string): ServiceEntry | undefined {\n return services.get(name);\n },\n\n getAllRepositories(): RepositoryEntry[] {\n return Array.from(repositories.values());\n },\n\n getRepository(name: string): RepositoryEntry | undefined {\n return repositories.get(name);\n },\n\n getAllSchemas(): SchemaEntry[] {\n return Array.from(schemas.values());\n },\n\n getSchema(name: string): SchemaEntry | undefined {\n return schemas.get(name);\n },\n\n clearRegistry(): void {\n modules.clear();\n aliases.clear();\n controllers.clear();\n services.clear();\n repositories.clear();\n schemas.clear();\n }\n };\n}\n\n/**\n * AsyncLocalStorage context that holds the active registry for the current execution scope.\n * Populated by createApp() — all code running within that scope can retrieve\n * the registry via getActiveRegistry().\n * @internal\n */\nexport const registryContext = new AsyncLocalStorage<InternalRegistry>();\n\n/**\n * Returns the registry bound to the current async execution context.\n * Throws REGISTRY_MISSING_CONTEXT if called outside a createApp() scope.\n * @internal — not exported from index.ts\n */\nexport function getActiveRegistry(): InternalRegistry {\n const store = registryContext.getStore();\n if (!store) {\n throw new NodulusError(\n 'REGISTRY_MISSING_CONTEXT',\n 'No active registry found in the current async context. Ensure code runs inside a createApp() execution scope.'\n );\n }\n return store;\n}\n\n/**\n * Returns a read-only view of the registry active in the current async context.\n * \n * @unstable This function is intended for advanced framework integrations or \n * internal debugging. The structure of the returned registry may change in future \n * minor updates. For standard use cases, rely on the properties returned by `createApp()`.\n */\nexport const getRegistry = (): NodulusRegistryAdvanced => getActiveRegistry();\n","export type NodulusErrorCode =\n | \"MODULE_NOT_FOUND\"\n | \"DUPLICATE_MODULE\"\n | \"MISSING_IMPORT\"\n | \"UNDECLARED_IMPORT\"\n | \"CIRCULAR_DEPENDENCY\"\n | \"EXPORT_MISMATCH\"\n | \"INVALID_CONTROLLER\"\n | \"ALIAS_NOT_FOUND\"\n | \"DUPLICATE_ALIAS\"\n | \"DUPLICATE_BOOTSTRAP\"\n | \"REGISTRY_MISSING_CONTEXT\"\n | \"INVALID_MODULE_DECLARATION\"\n | \"DUPLICATE_SERVICE\"\n | \"DUPLICATE_REPOSITORY\"\n | \"DUPLICATE_SCHEMA\"\n | \"INVALID_ESM_ENV\"\n | \"CLI_ERROR\";\n\nexport class NodulusError extends Error {\n readonly code: NodulusErrorCode;\n readonly details?: string;\n\n constructor(code: NodulusErrorCode, message: string, details?: string) {\n super(message);\n this.name = \"NodulusError\";\n this.code = code;\n this.details = details;\n }\n}\n\n","/**\n * Utility to detect circular dependencies in a directed graph.\n */\nexport function findCircularDependencies(dependencyMap: Map<string, string[]>): string[][] {\n const cycles: string[][] = [];\n const visited = new Set<string>();\n const recStack = new Set<string>();\n const path: string[] = [];\n\n const dfs = (node: string) => {\n visited.add(node);\n recStack.add(node);\n path.push(node);\n\n const deps = dependencyMap.get(node) || [];\n for (const neighbor of deps) {\n if (!visited.has(neighbor)) {\n dfs(neighbor);\n } else if (recStack.has(neighbor)) {\n // We hit a node currently in the stack (cycle detected)\n const cycleStart = path.indexOf(neighbor);\n cycles.push([...path.slice(cycleStart), neighbor]);\n }\n }\n\n recStack.delete(node);\n path.pop();\n };\n\n for (const node of dependencyMap.keys()) {\n if (!visited.has(node)) {\n dfs(node);\n }\n }\n\n return cycles;\n}\n","import path from 'node:path';\nimport { getActiveRegistry } from '../core/registry.js';\nimport { NodulusError } from '../core/errors.js';\nimport { getModuleCallerInfo } from '../core/caller.js';\nimport type { ModuleOptions } from '../types/index.js';\n\nexport function Module(name: string, options: ModuleOptions = {}): void {\n if (typeof name !== 'string') {\n throw new TypeError(`Module name must be a string, received ${typeof name}`);\n }\n\n const { filePath: indexPath, dirPath } = getModuleCallerInfo('Module()');\n\n // Rule 1: Name must match folder name\n if (dirPath) {\n const folderName = path.basename(dirPath);\n if (folderName && folderName !== name) {\n throw new NodulusError(\n 'INVALID_MODULE_DECLARATION',\n `Module name \"${name}\" does not match its containing folder \"${folderName}\".`,\n `The module name in Module() MUST match the folder name exactly.`\n );\n }\n }\n\n // Rule 2: Must be called from index file\n const fileName = path.basename(indexPath);\n const isIndexFile = /index\\.(ts|js|mts|mjs)$/.test(fileName);\n if (!isIndexFile) {\n throw new NodulusError(\n 'INVALID_MODULE_DECLARATION',\n `Module() was called from \"${fileName}\", but it must be called only from the module's index file.`,\n `File: ${indexPath}`\n );\n }\n\n getActiveRegistry().registerModule(name, options, dirPath, indexPath);\n}\n","import path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { NodulusError } from '../core/errors.js';\n\n/**\n * Internal utility — NOT part of the public Nodulus API.\n *\n * Walks the V8 call stack to find the file that called one of the Nodulus\n * identifier functions (Module, Service, Controller, Repository, Schema).\n *\n * Stack layout when an identifier function calls this helper:\n * 0 — resolveCallerFile (this function)\n * 1 — Module / Service / … (the identifier)\n * 2 — the user's source file (the caller we want)\n *\n */\nfunction resolveCallerFile(identifierName: string): string {\n const originalFunc = Error.prepareStackTrace;\n let callerFile: string | null = null;\n\n try {\n const err = new Error();\n Error.prepareStackTrace = (_, stack) => stack;\n const stack = err.stack as unknown as NodeJS.CallSite[];\n // Depth: 0 is resolveCallerFile, 1 is getCallerFileAndDir/getCallerFilePath, 2 is the identifier (Module, Service), 3 is the user's file\n if (stack && stack.length > 3) {\n callerFile = stack[3].getFileName() || null;\n }\n } catch {\n // getFileName() is unavailable in this environment;\n // the null-check below will throw a descriptive NodulusError.\n } finally {\n Error.prepareStackTrace = originalFunc;\n }\n\n if (!callerFile) {\n throw new NodulusError(\n 'INVALID_MODULE_DECLARATION',\n `${identifierName} could not determine caller path. Stack trace unavailable.`,\n 'Ensure you are using Node.js >= 20.6 with ESM and no bundler obfuscation.'\n );\n }\n\n // Normalise ESM file:// URLs to OS-native paths\n if (callerFile.startsWith('file://')) {\n callerFile = fileURLToPath(callerFile);\n }\n\n return callerFile;\n}\n\n/**\n * Returns the caller's file path and its containing directory.\n * Used by `Module()`, which needs both pieces to enforce naming rules.\n */\nexport function getModuleCallerInfo(\n identifierName: string\n): { filePath: string; dirPath: string } {\n const filePath = resolveCallerFile(identifierName);\n return { filePath, dirPath: path.dirname(filePath) };\n}\n\n/**\n * Returns only the caller's absolute file path.\n * Used by all non-Module identifiers (Service, Controller, Repository, Schema).\n */\nexport function getFileCallerInfo(\n identifierName: string\n): { filePath: string } {\n return { filePath: resolveCallerFile(identifierName) };\n}\n","import path from 'node:path';\nimport { getActiveRegistry } from '../core/registry.js';\nimport { getFileCallerInfo } from '../core/caller.js';\nimport type { ControllerOptions } from '../types/index.js';\n\nexport function Controller(prefix: string, options: ControllerOptions = {}): void {\n if (typeof prefix !== 'string') {\n throw new TypeError(`Controller prefix must be a string, received ${typeof prefix}`);\n }\n\n const { filePath } = getFileCallerInfo('Controller()');\n const name = path.parse(filePath).name;\n\n getActiveRegistry().registerControllerMetadata({\n name,\n path: filePath,\n prefix: prefix,\n middlewares: options.middlewares ?? [],\n enabled: options.enabled ?? true\n });\n}\n","import path from 'node:path';\nimport { getActiveRegistry } from '../core/registry.js';\nimport { getFileCallerInfo } from '../core/caller.js';\nimport type { ServiceOptions } from '../types/index.js';\n\n/**\n * Declares a file as a named service and registers it in the Nodulus registry.\n *\n * The `module` field is inferred from the parent folder name when not provided explicitly.\n *\n * @param name - Unique service name within the registry (e.g. 'UserService').\n * @param options - Optional configuration: module override and description.\n *\n * @example\n * // src/modules/users/users.service.ts\n * import { Service } from 'nodulus'\n *\n * Service('UserService', { module: 'users' })\n *\n * export const UserService = { ... }\n */\nexport function Service(name: string, options: ServiceOptions = {}): void {\n if (typeof name !== 'string' || name.trim() === '') {\n throw new TypeError(`Service name must be a non-empty string, received ${typeof name}`);\n }\n\n const { filePath } = getFileCallerInfo('Service()');\n\n // Infer module from the parent folder name if not explicitly provided\n const inferredModule = options.module ?? path.basename(path.dirname(filePath));\n\n getActiveRegistry().registerFileMetadata({\n name,\n path: filePath,\n type: 'service',\n module: inferredModule,\n description: options.description,\n });\n}\n","import path from 'node:path';\nimport { getActiveRegistry } from '../core/registry.js';\nimport { getFileCallerInfo } from '../core/caller.js';\nimport type { RepositoryOptions } from '../types/index.js';\n\n/**\n * Declares a file as a named repository and registers it in the Nodulus registry.\n *\n * The `module` field is inferred from the parent folder name when not provided explicitly.\n *\n * @param name - Unique repository name within the registry (e.g. 'UserRepository').\n * @param options - Optional configuration: module override, description, and data source type.\n *\n * @example\n * // src/modules/users/users.repository.ts\n * import { Repository } from 'nodulus'\n *\n * Repository('UserRepository', { module: 'users', source: 'database' })\n *\n * export const UserRepository = { ... }\n */\nexport function Repository(name: string, options: RepositoryOptions = {}): void {\n if (typeof name !== 'string' || name.trim() === '') {\n throw new TypeError(`Repository name must be a non-empty string, received ${typeof name}`);\n }\n\n const { filePath } = getFileCallerInfo('Repository()');\n\n // Infer module from the parent folder name if not explicitly provided\n const inferredModule = options.module ?? path.basename(path.dirname(filePath));\n\n getActiveRegistry().registerFileMetadata({\n name,\n path: filePath,\n type: 'repository',\n module: inferredModule,\n description: options.description,\n source: options.source,\n });\n}\n","import path from 'node:path';\nimport { getActiveRegistry } from '../core/registry.js';\nimport { getFileCallerInfo } from '../core/caller.js';\nimport type { SchemaOptions } from '../types/index.js';\n\n/**\n * Declares a file as a named validation schema and registers it in the Nodulus registry.\n *\n * The `module` field is inferred from the parent folder name when not provided explicitly.\n *\n * @param name - Unique schema name within the registry (e.g. 'CreateUserSchema').\n * @param options - Optional configuration: module override, description, and validation library.\n *\n * @example\n * // src/modules/users/users.schema.ts\n * import { Schema } from 'nodulus'\n *\n * Schema('CreateUserSchema', { module: 'users', library: 'zod' })\n *\n * export const CreateUserSchema = z.object({ ... })\n */\nexport function Schema(name: string, options: SchemaOptions = {}): void {\n if (typeof name !== 'string' || name.trim() === '') {\n throw new TypeError(`Schema name must be a non-empty string, received ${typeof name}`);\n }\n\n const { filePath } = getFileCallerInfo('Schema()');\n\n // Infer module from the parent folder name if not explicitly provided\n const inferredModule = options.module ?? path.basename(path.dirname(filePath));\n\n getActiveRegistry().registerFileMetadata({\n name,\n path: filePath,\n type: 'schema',\n module: inferredModule,\n description: options.description,\n library: options.library,\n });\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport fg from 'fast-glob';\nimport type { Application } from 'express';\nimport type { CreateAppOptions, NodulusApp } from '../types/index.js';\nimport { loadConfig } from '../core/config.js';\nimport { NodulusError } from '../core/errors.js';\nimport { createRegistry, registryContext } from '../core/registry.js';\nimport { activateAliasResolver } from '../aliases/resolver.js';\nimport { updateAliasCache } from '../aliases/cache.js';\nimport { createLogger } from '../core/logger.js';\nimport { performance } from 'node:perf_hooks';\nimport pc from 'picocolors';\n\nexport async function createApp(\n app: Application,\n options: CreateAppOptions = {}\n): Promise<NodulusApp> {\n // Step 0 — Prevent Duplicate Bootstrap\n if ((app as any).__nodulusBootstrapped) {\n throw new NodulusError(\n 'DUPLICATE_BOOTSTRAP',\n 'createApp() was called more than once with the same Express instance.'\n );\n }\n\n // Step 0.5 — ESM Environment Validation\n let isEsm = false;\n try {\n const pkgPath = path.resolve(process.cwd(), 'package.json');\n if (fs.existsSync(pkgPath)) {\n const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));\n if (pkg.type === 'module') {\n isEsm = true;\n }\n }\n } catch (_e) {\n // Failsafe, could not parse package.json, assume non-ESM to fail securely\n }\n\n if (!isEsm) {\n throw new NodulusError(\n 'INVALID_ESM_ENV',\n 'Nodulus requires an ESM environment. Please ensure \"type\": \"module\" is present in your root package.json file.'\n );\n }\n\n const registry = createRegistry();\n\n return registryContext.run(registry, async () => {\n const startTime = performance.now();\n try {\n\n // Step 1 — Load configuration\n const config = await loadConfig(options);\n const log = createLogger(config.logger, config.logLevel);\n\n if (config.domains || config.shared) {\n log.warn('Infrastructure (domains/shared) is not yet supported in v1.2.x. These keys in configuration will be ignored until v2.0.0.');\n }\n\n log.info('Bootstrap started', {\n modules: pc.cyan(config.modules),\n prefix: pc.cyan(config.prefix || '(none)'),\n strict: pc.yellow(String(config.strict)),\n nodeVersion: pc.gray(process.version),\n });\n\n // Step 2 — Resolve modules\n const globPattern = config.modules.replace(/\\\\/g, '/');\n const moduleDirs = await fg(globPattern, {\n onlyDirectories: true,\n absolute: true,\n cwd: process.cwd()\n });\n\n // Ensure strict alphabetical ordering\n moduleDirs.sort();\n\n // Store useful resolved paths for the upcoming steps\n const resolvedModules: { dirPath: string, indexPath: string }[] = [];\n\n for (const dirPath of moduleDirs) {\n log.debug(`Discovered module directory: ${dirPath}`, { dirPath });\n const tsPath = path.join(dirPath, 'index.ts');\n const jsPath = path.join(dirPath, 'index.js');\n \n let indexPath: string | null = null;\n \n if (fs.existsSync(tsPath)) {\n indexPath = tsPath;\n } else if (fs.existsSync(jsPath)) {\n indexPath = jsPath;\n }\n\n if (!indexPath) {\n throw new NodulusError(\n 'MODULE_NOT_FOUND',\n `No index.ts or index.js found for module. A module directory must have an index file mapping its dependencies.`,\n `Directory: ${dirPath}`\n );\n }\n \n resolvedModules.push({ dirPath, indexPath });\n }\n\n // Step 3 — Activate runtime aliases\n // Using pureModuleAliases to separate user configured folders vs magically generated modules\n if (config.resolveAliases !== false) {\n const pureModuleAliases: Record<string, string> = {};\n \n // Automatically resolve @modules/<name> for each module\n for (const mod of resolvedModules) {\n const modName = path.basename(mod.dirPath);\n const aliasKey = `@modules/${modName}`;\n \n // Dual mapping for runtime consistency (N-09)\n pureModuleAliases[aliasKey] = mod.indexPath;\n pureModuleAliases[`${aliasKey}/*`] = `${mod.dirPath}/*`;\n \n registry.registerAlias(aliasKey, mod.indexPath);\n registry.registerAlias(`${aliasKey}/*`, `${mod.dirPath}/*`);\n }\n\n await activateAliasResolver(pureModuleAliases, config.aliases, log);\n updateAliasCache(registry.getAllAliases());\n }\n\n // Step 4 — Import modules\n for (const mod of resolvedModules) {\n const imported = await import(pathToFileURL(mod.indexPath).href);\n\n // Correlate the imported module with the one added to the registry based on dirPath\n const allRegistered = registry.getAllModules();\n const registeredMod = allRegistered.find(m => path.normalize(m.path) === path.normalize(mod.dirPath));\n\n if (!registeredMod) {\n throw new NodulusError(\n 'MODULE_NOT_FOUND',\n `No index.ts found calling Module(). Add Module() to the module's index.ts.`,\n `File: ${mod.indexPath}`\n );\n }\n\n log.info(`Module loaded: ${pc.green(registeredMod.name)}`, {\n name: registeredMod.name,\n imports: registeredMod.imports,\n exports: registeredMod.exports,\n path: registeredMod.path,\n });\n\n // Validate Exports\n // CJS/ESM behavior: on dynamic imports, named exports are mapped as object keys.\n const actualExports = Object.keys(imported).filter(key => key !== 'default');\n const declaredExports = registeredMod.exports || [];\n\n for (const declared of declaredExports) {\n if (!actualExports.includes(declared)) {\n throw new NodulusError(\n 'EXPORT_MISMATCH',\n `A name declared in exports does not exist as a real export of index.ts.`,\n `Module: ${registeredMod.name}, Missing Export: ${declared}`\n );\n }\n }\n\n if (config.strict) {\n for (const actual of actualExports) {\n if (!declaredExports.includes(actual)) {\n log.warn(\n `Module \"${registeredMod.name}\" exports \"${actual}\" but it is not declared in Module() options \"exports\" array.`,\n { name: registeredMod.name, exportName: actual }\n );\n }\n }\n }\n }\n\n // Step 5 — Validate dependencies\n const allModules = registry.getAllModules();\n for (const mod of allModules) {\n for (const importName of mod.imports) {\n if (!registry.hasModule(importName)) {\n throw new NodulusError(\n 'MISSING_IMPORT',\n `A module declared in imports does not exist in the registry.`,\n `Module \"${mod.name}\" is trying to import missing module \"${importName}\"`\n );\n }\n }\n }\n\n // Strict mode validations for circular dependencies\n if (config.strict) {\n const cycles = registry.findCircularDependencies();\n if (cycles.length > 0) {\n const cycleStrings = cycles.map(cycle => cycle.join(' -> ')).join(' | ');\n throw new NodulusError(\n 'CIRCULAR_DEPENDENCY',\n `Circular dependency detected. Extract the shared dependency into a separate module.`,\n `Cycles found: ${cycleStrings}`\n );\n }\n }\n\n // Step 6 — Discover controllers\n for (const mod of allModules) {\n const rawMod = registry.getRawModule(mod.name);\n if (!rawMod) continue; // Failsafe, should always exist\n\n const files = await fg('**/*.{ts,js,mts,mjs,cjs}', {\n cwd: mod.path,\n absolute: true,\n ignore: [\n '**/*.types.*',\n '**/*.d.ts',\n '**/*.spec.*',\n '**/*.test.*',\n 'index.*' // Escapes root index.ts/js\n ]\n });\n\n files.sort();\n\n for (let file of files) {\n log.debug(`Scanning controller file: ${file}`, { filePath: file, module: mod.name });\n file = path.normalize(file);\n let imported: any;\n try {\n imported = await import(pathToFileURL(file).href);\n } catch (err: any) {\n throw new NodulusError(\n 'INVALID_CONTROLLER',\n `Failed to import controller file. Check for syntax errors or missing dependencies.`,\n `File: ${file} — ${err.message}`\n );\n }\n\n const resolvedFile = path.normalize(file);\n const ctrlMeta = registry.getControllerMetadata(resolvedFile) || registry.getAllControllersMetadata().find(c => path.normalize(c.path) === resolvedFile);\n if (ctrlMeta) {\n // Evaluate router validity (must be default export & resemble an Express router)\n const isRouter = imported.default && typeof imported.default === 'function' && typeof imported.default.use === 'function';\n \n if (!isRouter) {\n throw new NodulusError(\n 'INVALID_CONTROLLER',\n `Controller has no default export of a Router. Add export default router.`,\n `File: ${file}`\n );\n }\n\n log.debug(`Controller registered: ${pc.green(ctrlMeta.name)} → ${pc.cyan(ctrlMeta.prefix)}`, {\n name: ctrlMeta.name,\n prefix: ctrlMeta.prefix,\n module: mod.name,\n middlewareCount: ctrlMeta.middlewares.length,\n });\n\n // Bind the active Express Router instance directly to the internally saved metadata\n ctrlMeta.router = imported.default;\n rawMod.controllers.push(ctrlMeta);\n }\n }\n\n if (rawMod.controllers.length === 0) {\n log.warn(`Module \"${mod.name}\" has no controllers — no routes will be mounted from it`, {\n name: mod.name,\n path: mod.path,\n });\n }\n }\n\n // Step 7 — Mount routes\n const mountedRoutes: import('../types/index.js').MountedRoute[] = [];\n\n for (const mod of allModules) {\n const rawMod = registry.getRawModule(mod.name);\n if (!rawMod) continue;\n\n for (const ctrl of rawMod.controllers) {\n if (!ctrl.enabled) {\n log.info(`Controller \"${ctrl.name}\" is disabled — skipping mount`, {\n name: ctrl.name,\n module: mod.name,\n prefix: ctrl.prefix,\n });\n continue;\n }\n\n const fullPath = (config.prefix + ctrl.prefix).replace(/\\/+/g, '/').replace(/\\/$/, '') || '/';\n\n if (ctrl.router) {\n\n if (ctrl.middlewares && ctrl.middlewares.length > 0) {\n app.use(fullPath, ...ctrl.middlewares, ctrl.router);\n } else {\n app.use(fullPath, ctrl.router);\n }\n\n // Try to extract individual routes from Express router stack\n // If impossible, fallback to USE basepath.\n let foundRoutes = false;\n const extractedRoutes: { method: string, path: string }[] = [];\n\n if (ctrl.router.stack && Array.isArray(ctrl.router.stack)) {\n for (const layer of ctrl.router.stack) {\n const routeObj = layer.route as any;\n if (routeObj && routeObj.methods) {\n foundRoutes = true;\n const routePath = routeObj.path;\n const methods = Object.keys(routeObj.methods).filter(m => routeObj.methods[m]).map(m => m.toUpperCase());\n \n for (const method of methods) {\n const fullRoutePath = (fullPath + (routePath === '/' ? '' : routePath)).replace(/\\/+/g, '/');\n extractedRoutes.push({ method, path: fullRoutePath });\n mountedRoutes.push({\n method: method as any,\n path: fullRoutePath,\n module: mod.name,\n controller: ctrl.name\n });\n }\n }\n }\n }\n\n if (!foundRoutes) {\n extractedRoutes.push({ method: 'USE', path: fullPath });\n mountedRoutes.push({\n method: 'USE',\n path: fullPath,\n module: mod.name,\n controller: ctrl.name\n });\n }\n\n const methodColors: Record<string, (msg: string) => string> = {\n GET: pc.green,\n POST: pc.yellow,\n PUT: pc.cyan,\n PATCH: pc.magenta,\n DELETE: pc.red,\n USE: pc.gray,\n };\n\n for (const route of extractedRoutes) {\n const colorFn = methodColors[route.method] || pc.white;\n log.info(` ${colorFn(route.method.padEnd(6))} ${pc.white(route.path)} ${pc.gray(`(${ctrl.name})`)}`, {\n method: route.method,\n path: route.path,\n module: mod.name,\n controller: ctrl.name,\n });\n }\n }\n }\n }\n\n // Tag Express app to prevent double boot\n (app as any).__nodulusBootstrapped = true;\n\n // Step 8 — Return NodulusApp\n const safeRegisteredModules = allModules.map(m => registry.getModule(m.name)!);\n \n const durationMs = Math.round(performance.now() - startTime);\n log.info(`${pc.green('Bootstrap complete')} — ${pc.cyan(allModules.length)} module(s), ${pc.cyan(mountedRoutes.length)} route(s) in ${pc.yellow(`${durationMs}ms`)}`, {\n moduleCount: allModules.length,\n routeCount: mountedRoutes.length,\n durationMs,\n });\n\n return {\n modules: safeRegisteredModules,\n routes: mountedRoutes,\n registry\n };\n\n } catch (err) {\n // Rollback: discard any partially registered state so a retry\n // does not encounter leftover modules or aliases.\n registry.clearRegistry();\n throw err;\n }\n });\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport type { CreateAppOptions, ResolvedConfig, NodulusConfig } from '../types/index.js';\nimport { defaultLogHandler, resolveLogLevel } from './logger.js';\n\nconst defaultStrict = typeof process !== 'undefined' && process.env?.NODE_ENV !== 'production';\n\nexport const DEFAULTS: ResolvedConfig = {\n modules: 'src/modules/*',\n domains: undefined,\n shared: undefined,\n prefix: '',\n aliases: {},\n strict: defaultStrict,\n resolveAliases: true,\n logger: defaultLogHandler,\n logLevel: resolveLogLevel(),\n nits: {\n enabled: true,\n similarityThreshold: undefined, // Use dynamic by default\n registryPath: '.nodulus/registry.json'\n }\n};\n\nexport const loadConfig = async (options: CreateAppOptions = {}): Promise<ResolvedConfig> => {\n const cwd = process.cwd();\n \n let fileConfig: NodulusConfig = {};\n \n const tsPath = path.join(cwd, 'nodulus.config.ts');\n const jsPath = path.join(cwd, 'nodulus.config.js');\n \n const candidates: string[] = [tsPath, jsPath];\n\n let configPathToLoad: string | null = null;\n\n for (const candidate of candidates) {\n if (fs.existsSync(candidate)) {\n configPathToLoad = candidate;\n break;\n }\n }\n\n if (configPathToLoad) {\n try {\n const importUrl = pathToFileURL(configPathToLoad).href;\n const mod = await import(importUrl);\n fileConfig = mod.default || mod.config || mod;\n } catch (error: any) {\n if (configPathToLoad.endsWith('.ts') && error.code === 'ERR_UNKNOWN_FILE_EXTENSION') {\n throw new Error(\n `[Nodulus] Found \"nodulus.config.ts\" but your environment cannot load raw TypeScript files.\\n` +\n ` - In production: Run \"npm run build\" to generate a .js config OR use nodulus.config.js.\\n` +\n ` - In development: Ensure you are running with a loader like \"tsx\" or \"ts-node\".`,\n { cause: error }\n );\n }\n throw new Error(`[Nodulus] Failed to parse or evaluate config file at ${configPathToLoad}: ${error.message}`, { cause: error });\n }\n }\n\n // Merge strategy: options > fileConfig > defaults\n return {\n modules: options.modules ?? fileConfig.modules ?? DEFAULTS.modules,\n domains: options.domains ?? fileConfig.domains ?? DEFAULTS.domains,\n shared: options.shared ?? fileConfig.shared ?? DEFAULTS.shared,\n prefix: options.prefix ?? fileConfig.prefix ?? DEFAULTS.prefix,\n aliases: {\n ...DEFAULTS.aliases,\n ...(fileConfig.aliases || {}),\n ...(options.aliases || {}) // Options override file aliases\n },\n strict: options.strict ?? fileConfig.strict ?? DEFAULTS.strict,\n resolveAliases: options.resolveAliases ?? fileConfig.resolveAliases ?? DEFAULTS.resolveAliases,\n logger: options.logger ?? fileConfig.logger ?? DEFAULTS.logger,\n logLevel: resolveLogLevel(options.logLevel ?? fileConfig.logLevel),\n nits: {\n enabled: options.nits?.enabled ?? fileConfig.nits?.enabled ?? DEFAULTS.nits.enabled,\n similarityThreshold: options.nits?.similarityThreshold ?? fileConfig.nits?.similarityThreshold ?? DEFAULTS.nits.similarityThreshold,\n registryPath: options.nits?.registryPath ?? fileConfig.nits?.registryPath ?? DEFAULTS.nits.registryPath\n }\n };\n};\n","import pc from 'picocolors';\nimport type { LogLevel, LogHandler } from '../types/index.js';\n\nconst LEVEL_ORDER: Record<LogLevel, number> = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n};\n\nconst LEVEL_STYLE: Record<LogLevel, (msg: string) => string> = {\n debug: (msg) => pc.gray(msg),\n info: (msg) => pc.cyan(msg),\n warn: (msg) => pc.yellow(msg),\n error: (msg) => pc.red(msg),\n};\n\nconst LEVEL_LABELS: Record<LogLevel, string> = {\n debug: 'debug',\n info: 'info ', // trailing space for alignment\n warn: 'warn ',\n error: 'error',\n};\n\n/**\n * Default log handler. Writes to process.stdout (info/debug) or process.stderr (warn/error).\n * All lines are prefixed with [Nodulus].\n */\nexport const defaultLogHandler: LogHandler = (level, message) => {\n const prefix = pc.gray('[Nodulus]');\n const label = LEVEL_STYLE[level](LEVEL_LABELS[level]);\n const line = `${prefix} ${label} ${message}`;\n \n if (level === 'warn' || level === 'error') {\n process.stderr.write(line + '\\n');\n } else {\n process.stdout.write(line + '\\n');\n }\n};\n\n/**\n * Resolves the effective minimum log level.\n * Priority: explicit logLevel option > NODE_DEBUG env var > default ('info').\n */\nexport function resolveLogLevel(explicit?: LogLevel): LogLevel {\n if (explicit) return explicit;\n\n const nodeDebug = process.env.NODE_DEBUG ?? '';\n if (nodeDebug.split(',').map(s => s.trim()).includes('nodulus')) {\n return 'debug';\n }\n\n return 'info';\n}\n\nexport interface Logger {\n debug(message: string, meta?: Record<string, unknown>): void;\n info(message: string, meta?: Record<string, unknown>): void;\n warn(message: string, meta?: Record<string, unknown>): void;\n error(message: string, meta?: Record<string, unknown>): void;\n}\n\n/**\n * Creates a bound logger that filters by minLevel and delegates to handler.\n * \n * @param handler - Where log events are sent.\n * @param minLevel - Events below this level are discarded.\n */\nexport function createLogger(handler: LogHandler, minLevel: LogLevel): Logger {\n const minOrder = LEVEL_ORDER[minLevel];\n\n const emit = (level: LogLevel, message: string, meta?: Record<string, unknown>) => {\n if (LEVEL_ORDER[level] >= minOrder) {\n handler(level, message, meta);\n }\n };\n\n return {\n debug: (msg, meta) => emit('debug', msg, meta),\n info: (msg, meta) => emit('info', msg, meta),\n warn: (msg, meta) => emit('warn', msg, meta),\n error: (msg, meta) => emit('error', msg, meta),\n };\n}\n","import { register } from 'node:module';\nimport { pathToFileURL } from 'node:url';\nimport type { Logger } from '../core/logger.js';\n\n// Node.js Customization Hooks types\nexport type ResolveHookContext = {\n conditions: string[];\n parentURL?: string;\n data?: unknown;\n};\n\nexport type NextResolve = (specifier: string, context?: ResolveHookContext) => Promise<{ shortCircuit?: boolean; url: string }>;\n\nexport type ResolveHook = (\n specifier: string,\n context: ResolveHookContext,\n nextResolve: NextResolve\n) => Promise<{ shortCircuit?: boolean; url: string }>;\n\nlet isHookRegistered = false;\nlet registrationPromise: Promise<void> | null = null;\n\n/** @internal exclusively for tests */\nexport function clearAliasResolverOptions(): void {\n isHookRegistered = false;\n registrationPromise = null;\n}\n\n/**\n * Activates the ESM Alias Resolver using Node.js module.register.\n * \n * Limitation: This ESM hook is strictly for Node ESM pipelines (Node >= 20.6.0).\n * It will not function effectively in pure CJS pipelines without a transpiler or loader.\n * For CJS and bundlers (Vite, esbuild), use getAliases() to configure their specific resolvers.\n */\nexport async function activateAliasResolver(moduleAliases: Record<string, string>, folderAliases: Record<string, string>, log: Logger): Promise<void> {\n if (isHookRegistered) return;\n if (registrationPromise) return registrationPromise;\n\n registrationPromise = (async () => {\n try {\n const combinedAliases = { ...moduleAliases, ...folderAliases };\n\n for (const [alias, target] of Object.entries(folderAliases)) {\n log.debug(`Alias registered: ${alias} → ${target}`, { alias, target, source: 'config' });\n }\n for (const [alias, target] of Object.entries(moduleAliases)) {\n log.debug(`Alias registered: ${alias} → ${target}`, { alias, target, source: 'module' });\n }\n\n // Aliases are serialised directly into the hook source so they are available\n // in the hook's closure regardless of whether Node.js propagates context.data\n // across all resolution chains (not guaranteed in every Node 20.6+ build).\n const serialisedAliases = JSON.stringify(combinedAliases);\n\n const loaderCode = `\nimport { pathToFileURL } from 'node:url';\nimport path from 'node:path';\n\nconst aliases = ${serialisedAliases};\n\nexport async function resolve(specifier, context, nextResolve) {\n for (const alias of Object.keys(aliases)) {\n if (alias.endsWith('/*')) {\n const baseAlias = alias.slice(0, -2);\n if (specifier.startsWith(baseAlias + '/')) {\n const baseTarget = aliases[alias].slice(0, -2);\n const subPath = specifier.slice(baseAlias.length + 1);\n const resolvedPath = path.resolve(baseTarget, subPath);\n return nextResolve(pathToFileURL(resolvedPath).href, context);\n }\n } else if (specifier === alias) {\n const target = aliases[alias];\n return nextResolve(pathToFileURL(path.resolve(target)).href, context);\n }\n }\n return nextResolve(specifier, context);\n}\n`;\n\n const dataUrl = `data:text/javascript,${encodeURIComponent(loaderCode)}`;\n const parentUrl = import.meta.url;\n \n if (typeof register === 'function') {\n register(dataUrl, { parentURL: parentUrl });\n isHookRegistered = true;\n log.info(`ESM alias hook activated (${Object.keys(combinedAliases).length} alias(es))`, {\n aliasCount: Object.keys(combinedAliases).length\n });\n } else {\n log.warn('ESM alias hook could not be registered — upgrade to Node.js >= 20.6.0 for runtime alias support', {\n nodeVersion: process.version\n });\n }\n } catch (err) {\n log.warn('ESM alias hook registration threw an unexpected error — aliases may not resolve at runtime', {\n error: (err as any)?.message ?? String(err)\n });\n } finally {\n registrationPromise = null;\n }\n })();\n\n return registrationPromise;\n}\n","import { registryContext } from '../core/registry.js';\n\n// Limitation: last write wins in parallel tests if not running within a registry context.\n// When running within createApp(), the registry is the source of truth.\nlet globalAliasCache: Record<string, string> = {};\n\nexport function updateAliasCache(aliases: Record<string, string>): void {\n globalAliasCache = { ...aliases };\n}\n\nexport function getAliasCache(): Record<string, string> {\n const activeRegistry = registryContext.getStore();\n if (activeRegistry) {\n return activeRegistry.getAllAliases();\n }\n return globalAliasCache;\n}\n\nexport function clearAliasCache(): void {\n globalAliasCache = {};\n}\n","import path from 'node:path';\nimport { getAliasCache } from './cache.js';\nimport type { GetAliasesOptions } from '../types/index.js';\n\nexport async function getAliases(options: GetAliasesOptions = {}): Promise<Record<string, string>> {\n const includeFolders = options.includeFolders ?? true;\n const absolute = options.absolute ?? false;\n\n const allAliases = getAliasCache();\n const result: Record<string, string> = {};\n const cwd = process.cwd();\n \n for (const [alias, target] of Object.entries(allAliases)) {\n if (!includeFolders && !alias.startsWith('@modules/')) {\n continue;\n }\n \n let resolvedPath: string;\n \n if (absolute) {\n resolvedPath = path.isAbsolute(target) ? target : path.resolve(cwd, target);\n // Extra step if it's a @modules to point to index specifically (optional, but often useful for bundlers resolving dynamic exports)\n // Actually, we maintain exactly what is stored!\n } else {\n resolvedPath = path.isAbsolute(target) ? path.relative(cwd, target) : target;\n \n // Ensure positive POSIX formatting for bundlers\n resolvedPath = resolvedPath.replace(/\\\\/g, '/');\n if (!resolvedPath.startsWith('.') && !resolvedPath.startsWith('/')) {\n resolvedPath = './' + resolvedPath;\n }\n }\n \n result[alias] = resolvedPath;\n }\n \n return result;\n}\n"],"mappings":"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","names":["path","path","stack","path","path","path","path","path","path","path","path","path","fs","path","pathToFileURL","path","path","pc","path","fs","pathToFileURL","path","path"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vlynk-studios/nodulus-core",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.5",
|
|
4
4
|
"description": "A lightweight structural layer for Express with native ESM hooks support.",
|
|
5
5
|
"author": "Vlynk Studios & Keiver-dev",
|
|
6
6
|
"license": "MIT",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
},
|
|
45
45
|
"homepage": "https://github.com/Vlynk-Studios/nodulus-core#readme",
|
|
46
46
|
"peerDependencies": {
|
|
47
|
-
"express": ">=
|
|
47
|
+
"express": ">=5.0.0"
|
|
48
48
|
},
|
|
49
49
|
"engines": {
|
|
50
50
|
"node": ">=20.6.0"
|