'use strict'; var destr = require('destr'); var flat = require('flat'); var fs = require('node:fs'); var fg = require('fast-glob'); var path = require('node:path'); var ebec = require('ebec'); var jiti = require('jiti'); var node_url = require('node:url'); var yaml = require('yaml'); function hasOwnProperty(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); } function hasStringProperty(obj, prop) { return hasOwnProperty(obj, prop) && typeof obj[prop] === 'string'; } /* * Copyright (c) 2022. * Author Peter Placzek (tada5hi) * For the full copyright and license information, * view the LICENSE file that was distributed with this source code. */ function isObject(item) { return !!item && typeof item === 'object' && !Array.isArray(item); } function isSafeObjectKey(key) { return key !== '__proto__' && key !== 'prototype' && key !== 'constructor'; } function handleException(e) { if (e instanceof Error) { throw e; } const error = new Error('Can not process thrown exception.'); if (isObject(e)) { if (hasOwnProperty(e, 'message') && typeof e.message === 'string') { error.message = e.message; } if (hasOwnProperty(e, 'stack') && typeof e.stack === 'string') { error.stack = e.stack; } } throw error; } function getFileNameExtension(input, allowed) { const extension = path.extname(input); if (extension === '' || extension === '.') { return undefined; } if (typeof allowed === 'undefined' || allowed.indexOf(extension) !== -1) { return extension; } return undefined; } function removeFileNameExtension(input, extensions) { const extension = getFileNameExtension(input, extensions); if (extension) { return input.substring(0, input.length - extension.length); } return input; } /* * Copyright (c) 2022. * Author Peter Placzek (tada5hi) * For the full copyright and license information, * view the LICENSE file that was distributed with this source code. */ function toArray(input) { return Array.isArray(input) ? input : [ input ]; } function isFilePath(input) { const extension = path.extname(input); return extension && extension !== ''; } /* * Copyright (c) 2024. * Author Peter Placzek (tada5hi) * For the full copyright and license information, * view the LICENSE file that was distributed with this source code. */ function isJestRuntimeEnvironment() { return process.env && process.env.JEST_WORKER_ID !== undefined; } function isTsNodeRuntimeEnvironment() { // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore return !!process[Symbol.for('ts-node.register.instance')]; } function isTypeScriptError(input) { if (!isObject(input)) { return false; } if (typeof input.diagnosticCodes !== 'undefined') { return true; } return typeof input.message === 'string' && /TS\d+/.test(input.message); } function buildLocatorPatterns(pattern) { return Array.isArray(pattern) ? pattern : [ pattern ]; } function buildLocatorOptions(options = {}) { const paths = options.path ? toArray(options.path) : []; const ignore = options.ignore ? toArray(options.ignore) : []; if (paths.length === 0) { paths.push(process.cwd()); } let onlyFiles; let onlyDirectories; if (options.onlyDirectories === options.onlyFiles) { onlyDirectories = false; onlyFiles = !options.onlyDirectories; } else if (typeof options.onlyFiles === 'undefined') { onlyDirectories = options.onlyDirectories ?? false; onlyFiles = !options.onlyDirectories; } else { onlyFiles = options.onlyFiles ?? true; onlyDirectories = !options.onlyFiles; } return { path: paths, ignore, onlyDirectories, onlyFiles }; } function pathToLocatorInfo(input, skipResolve) { if (!skipResolve && !path.isAbsolute(input)) { input = path.resolve(process.cwd(), input); } const info = path.parse(input); return { path: info.dir.split('/').join(path.sep), name: info.name, extension: info.ext ? info.ext : undefined }; } function isLocatorInfo(input) { return isObject(input) && typeof input.path === 'string' && typeof input.name === 'string' && typeof input.extension === 'string'; } function buildFilePath(input) { if (typeof input === 'string') { return input; } if (input.extension) { return path.join(input.path, input.name) + input.extension; } return path.join(input.path, input.name); } function buildFilePathWithoutExtension(input) { let info; if (typeof input === 'string') { info = pathToLocatorInfo(input); } else { info = input; } return path.join(info.path, info.name); } async function locateMany(pattern, options) { const patterns = buildLocatorPatterns(pattern); const opts = buildLocatorOptions(options); const items = []; for(let i = 0; i < patterns.length; i++){ for(let j = 0; j < opts.path.length; j++){ const files = await fg(patterns[i], { absolute: true, cwd: opts.path[j], ignore: opts.ignore, onlyFiles: opts.onlyFiles, onlyDirectories: opts.onlyDirectories }); for(let k = 0; k < files.length; k++){ items.push(pathToLocatorInfo(files[k], true)); } } } return items; } async function locate(pattern, options) { const patterns = buildLocatorPatterns(pattern); const opts = buildLocatorOptions(options); for(let i = 0; i < patterns.length; i++){ for(let j = 0; j < opts.path.length; j++){ const files = await fg(patterns[i], { absolute: true, cwd: opts.path[j], ignore: opts.ignore, onlyFiles: opts.onlyFiles, onlyDirectories: opts.onlyDirectories }); const element = files.shift(); if (element) { return pathToLocatorInfo(element, true); } } } return undefined; } function locateManySync(pattern, options) { const patterns = buildLocatorPatterns(pattern); const opts = buildLocatorOptions(options); const items = []; for(let i = 0; i < patterns.length; i++){ for(let j = 0; j < opts.path.length; j++){ const files = fg.sync(patterns[i], { absolute: true, cwd: opts.path[j], ignore: opts.ignore, onlyFiles: opts.onlyFiles, onlyDirectories: opts.onlyDirectories }); for(let k = 0; k < files.length; k++){ items.push(pathToLocatorInfo(files[k], true)); } } } return items; } function locateSync(pattern, options) { const patterns = buildLocatorPatterns(pattern); const opts = buildLocatorOptions(options); for(let i = 0; i < patterns.length; i++){ for(let j = 0; j < opts.path.length; j++){ const files = fg.sync(patterns[i], { absolute: true, cwd: opts.path[j], ignore: opts.ignore, onlyFiles: opts.onlyFiles, onlyDirectories: opts.onlyDirectories }); const element = files.shift(); if (element) { return pathToLocatorInfo(element, true); } } } return undefined; } /* * Copyright (c) 2022-2023. * Author Peter Placzek (tada5hi) * For the full copyright and license information, * view the LICENSE file that was distributed with this source code. */ // Based on https://github.com/unjs/rc9 (MIT) class ConfLoader { async execute(input) { const filePath = buildFilePath(input); try { const file = await fs.promises.readFile(filePath, { encoding: 'utf-8' }); return this.parse(file); } catch (e) { return handleException(e); } } executeSync(input) { const filePath = buildFilePath(input); try { const file = fs.readFileSync(filePath, { encoding: 'utf-8' }); return this.parse(file); } catch (e) { return handleException(e); } } parse(contents) { const config = {}; const lines = contents.split(/\n|\r|\r\n/); for(let i = 0; i < lines.length; i++){ const match = lines[i].match(/^\s*([^\s=]+)\s*=\s*(.*)?\s*$/); if (!match) { continue; } // Key const key = match[1]; if (!key || !isSafeObjectKey(key)) { continue; } const value = destr.destr(match[2].trim()); if (key.endsWith('[]')) { const arrKey = key.slice(0, Math.max(0, key.length - 2)); config[arrKey] = (config[arrKey] || []).concat(value); continue; } config[key] = value; } return flat.unflatten(config, { overwrite: true }); } } function isESModule(input) { return isObject(input) && // eslint-disable-next-line no-underscore-dangle typeof input.__esModule !== 'undefined'; } // https://2ality.com/2017/01/babel-esm-spec-mode.html function toModuleRecord(data) { if (isESModule(data)) { // @see https://github.com/testing-library/user-event/issues/813 // @see https://stackoverflow.com/questions/62717394/export-default-class-exports-double-nested-default if (isESModule(data.default) && data.default.default) { return { ...data, default: data.default.default }; } return data; } const output = Object.create(null, { __esModule: { value: true }, [Symbol.toStringTag]: { value: 'Module' } }); if (isObject(data)) { // eslint-disable-next-line no-restricted-syntax for(const key in data){ if (hasOwnProperty(output, key)) { continue; } let descriptor = Object.getOwnPropertyDescriptor(data, key); if (!descriptor || 'get' in descriptor || descriptor.writable || descriptor.configurable) { descriptor = { enumerable: true, get () { return data[key]; } }; } Object.defineProperty(output, key, descriptor); } } if (!hasOwnProperty(output, 'default')) { Object.defineProperty(output, 'default', { value: data, enumerable: true }); } return Object.freeze(output); } function getModuleExport(data, filterFn) { const keys = Object.keys(data); for(let i = 0; i < keys.length; i++){ if (filterFn(keys[i], data[keys[i]])) { return { key: keys[i], value: data[keys[i]] }; } } return undefined; } class ModuleLoader { async execute(input) { let output; try { output = await this.load(input); } catch (e) { if (e instanceof SyntaxError || e instanceof ReferenceError || isTypeScriptError(e)) { throw e; } // jiti + ts-node // issue: https://github.com/nuxt/bridge/issues/228 if (isTsNodeRuntimeEnvironment()) { output = this.loadSync(input); } else { output = this.instance(input); } } return toModuleRecord(output); } executeSync(input) { let output; try { output = this.loadSync(input); } catch (e) { if (e instanceof SyntaxError || e instanceof ReferenceError || isTypeScriptError(e)) { throw e; } output = this.instance(input); } return toModuleRecord(output); } // --------------------------------------------------------------------------- async load(data, options = {}) { const id = this.build(data, options); try { // segmentation fault // issue: https://github.com/nodejs/node/issues/35889 if (isJestRuntimeEnvironment()) { // eslint-disable-next-line global-require,import/no-dynamic-require return require(id); } return await import(id); } catch (e) { /* istanbul ignore next */ if (isObject(e) && hasStringProperty(e, 'code')) { if (!options.withFilePrefix && (e.code === 'ERR_UNSUPPORTED_ESM_URL_SCHEME' || e.code === 'UNSUPPORTED_ESM_URL_SCHEME')) { return this.load(data, { ...options, withFilePrefix: true }); } throw new ebec.BaseError({ code: e.code, message: hasStringProperty(e, 'message') ? e.message : undefined, stack: hasStringProperty(e, 'stack') ? e.stack : undefined }); } /* istanbul ignore next */ return handleException(e); } } loadSync(data, options = {}) { const id = this.build(data, options); try { // eslint-disable-next-line global-require,import/no-dynamic-require return require(id); } catch (e) { /* istanbul ignore next */ if (isObject(e) && hasStringProperty(e, 'code')) { throw new ebec.BaseError({ code: e.code, message: hasStringProperty(e, 'message') ? e.message : undefined, stack: hasStringProperty(e, 'stack') ? e.stack : undefined }); } return handleException(e); } } build(data, options = {}) { if (isLocatorInfo(data) || isFilePath(data)) { if (typeof data !== 'string') { data = buildFilePath(data); } if (options.withFilePrefix) { data = node_url.pathToFileURL(data).href; } } return data; } constructor(){ // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore this.instance = jiti.createJiti(undefined, { extensions: [ '.js', '.mjs', '.mts', '.cjs', '.cts', '.ts' ] }); } } class JSONLoader { async execute(input) { const filePath = buildFilePath(input); try { const file = await fs.promises.readFile(filePath, { encoding: 'utf-8' }); return JSON.parse(file); } catch (e) { return handleException(e); } } executeSync(input) { const filePath = buildFilePath(input); try { const file = fs.readFileSync(filePath, { encoding: 'utf-8' }); return JSON.parse(file); } catch (e) { return handleException(e); } } } class YAMLLoader { async execute(input) { const filePath = buildFilePath(input); try { const file = await fs.promises.readFile(filePath, { encoding: 'utf-8' }); return yaml.parse(file); } catch (e) { return handleException(e); } } executeSync(input) { const filePath = buildFilePath(input); try { const file = fs.readFileSync(filePath, { encoding: 'utf-8' }); return yaml.parse(file); } catch (e) { return handleException(e); } } } /* * Copyright (c) 2023. * Author Peter Placzek (tada5hi) * For the full copyright and license information, * view the LICENSE file that was distributed with this source code. */ var LoaderId = /*#__PURE__*/ function(LoaderId) { LoaderId["MODULE"] = "module"; LoaderId["JSON"] = "json"; LoaderId["CONF"] = "conf"; LoaderId["YAML"] = "yaml"; return LoaderId; }({}); class LoaderManager { register(test, loader) { if (typeof loader !== 'undefined') { this.rules.push({ test, loader }); return; } this.rules.push(test); } async execute(input) { const id = this.findLoader(input); if (!id) { const info = pathToLocatorInfo(input); throw new Error(`No loader registered for extension: "${info.extension}"`); } const loader = this.resolve(id); return loader.execute(input); } executeSync(input) { const id = this.findLoader(input); if (!id) { const info = pathToLocatorInfo(input); throw new Error(`No loader registered for extension: ${info.extension || 'unknown'}`); } const loader = this.resolve(id); return loader.executeSync(input); } findLoader(input) { if (!isFilePath(input)) { return LoaderId.MODULE; } const info = pathToLocatorInfo(input); for(let i = 0; i < this.rules.length; i++){ const { test } = this.rules[i]; if (Array.isArray(test)) { if (info.extension && test.indexOf(info.extension) !== -1) { return this.rules[i].loader; } } else if (test.test(buildFilePath(info))) { return this.rules[i].loader; } } return undefined; } /** * Resolve loader by id. * * @param id */ resolve(id) { if (typeof id !== 'string') { return id; } if (Object.prototype.hasOwnProperty.call(this.loaders, id)) { return this.loaders[id]; } let loader; // built-in switch(id){ case LoaderId.CONF: { loader = new ConfLoader(); break; } case LoaderId.MODULE: { loader = new ModuleLoader(); break; } case LoaderId.JSON: { loader = new JSONLoader(); break; } case LoaderId.YAML: { loader = new YAMLLoader(); break; } /* istanbul ignore next */ default: { const pluginPath = this.normalizePath(id); const moduleLoader = this.resolve(LoaderId.MODULE); loader = moduleLoader.executeSync(pluginPath); break; } } if (typeof loader !== 'undefined') { this.loaders[id] = loader; return loader; } throw new Error(`The loader ${id} could not be resolved.`); } /* istanbul ignore next */ normalizePath(input) { if (path.isAbsolute(input) || input.startsWith('./')) { return input; } if (input.startsWith('module:')) { return input.substring(0, 'module:'.length); } if (!input.startsWith('@')) { return `@locter/${input}`; } return input; } constructor(){ this.loaders = {}; this.rules = [ { test: [ '.js', '.mjs', '.mts', '.cjs', '.cts', '.ts' ], loader: LoaderId.MODULE }, { test: [ '.conf' ], loader: LoaderId.CONF }, { test: [ '.json' ], loader: LoaderId.JSON }, { test: [ '.yml', '.yaml' ], loader: LoaderId.YAML } ]; } } let instance; function useLoader() { if (typeof instance !== 'undefined') { return instance; } instance = new LoaderManager(); return instance; } function registerLoader(test, loader) { const manager = useLoader(); if (typeof loader !== 'undefined') { manager.register(test, loader); return; } manager.register(test); } async function load(input) { const manager = useLoader(); if (typeof input === 'string') { return manager.execute(input); } return manager.execute(buildFilePath(input)); } function loadSync(input) { const manager = useLoader(); if (typeof input === 'string') { return manager.executeSync(input); } return manager.executeSync(buildFilePath(input)); } exports.ConfLoader = ConfLoader; exports.JSONLoader = JSONLoader; exports.LoaderManager = LoaderManager; exports.ModuleLoader = ModuleLoader; exports.buildFilePath = buildFilePath; exports.buildFilePathWithoutExtension = buildFilePathWithoutExtension; exports.buildLocatorOptions = buildLocatorOptions; exports.buildLocatorPatterns = buildLocatorPatterns; exports.getFileNameExtension = getFileNameExtension; exports.getModuleExport = getModuleExport; exports.handleException = handleException; exports.hasOwnProperty = hasOwnProperty; exports.hasStringProperty = hasStringProperty; exports.isESModule = isESModule; exports.isFilePath = isFilePath; exports.isJestRuntimeEnvironment = isJestRuntimeEnvironment; exports.isLocatorInfo = isLocatorInfo; exports.isObject = isObject; exports.isSafeObjectKey = isSafeObjectKey; exports.isTsNodeRuntimeEnvironment = isTsNodeRuntimeEnvironment; exports.isTypeScriptError = isTypeScriptError; exports.load = load; exports.loadSync = loadSync; exports.locate = locate; exports.locateMany = locateMany; exports.locateManySync = locateManySync; exports.locateSync = locateSync; exports.pathToLocatorInfo = pathToLocatorInfo; exports.registerLoader = registerLoader; exports.removeFileNameExtension = removeFileNameExtension; exports.toArray = toArray; exports.toModuleRecord = toModuleRecord; //# sourceMappingURL=index.cjs.map