@kubb/core
Version:
Core functionality for Kubb's plugin-based code generation system, providing the foundation for transforming OpenAPI specifications.
1,093 lines (1,076 loc) • 32.9 kB
JavaScript
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var chunkMCNA6SYG_cjs = require('./chunk-MCNA6SYG.cjs');
var chunkQR7CQIA3_cjs = require('./chunk-QR7CQIA3.cjs');
var chunkBHSTNFNQ_cjs = require('./chunk-BHSTNFNQ.cjs');
var chunkE4XLCCPK_cjs = require('./chunk-E4XLCCPK.cjs');
var pLimit2 = require('p-limit');
var path3 = require('path');
var remeda = require('remeda');
var mod = require('module');
var os = require('os');
var url = require('url');
var process2 = require('process');
var fs = require('fs');
var semver = require('semver');
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
var pLimit2__default = /*#__PURE__*/_interopDefault(pLimit2);
var path3__default = /*#__PURE__*/_interopDefault(path3);
var mod__default = /*#__PURE__*/_interopDefault(mod);
var os__default = /*#__PURE__*/_interopDefault(os);
var process2__default = /*#__PURE__*/_interopDefault(process2);
var fs__default = /*#__PURE__*/_interopDefault(fs);
function hookSeq(promises) {
return promises.filter(Boolean).reduce(
(promise, func) => {
if (typeof func !== "function") {
throw new Error("HookSeq needs a function that returns a promise `() => Promise<unknown>`");
}
return promise.then((state) => {
const calledFunc = func(state);
if (calledFunc) {
return calledFunc.then(Array.prototype.concat.bind(state));
}
});
},
Promise.resolve([])
);
}
function hookFirst(promises, nullCheck = (state) => state !== null) {
let promise = Promise.resolve(null);
for (const func of promises.filter(Boolean)) {
promise = promise.then((state) => {
if (nullCheck(state)) {
return state;
}
return func(state);
});
}
return promise;
}
function hookParallel(promises, concurrency = Number.POSITIVE_INFINITY) {
const limit = pLimit2__default.default(concurrency);
const tasks = promises.filter(Boolean).map((promise) => limit(() => promise()));
return Promise.allSettled(tasks);
}
// src/PromiseManager.ts
var PromiseManager = class {
#options = {};
constructor(options = {}) {
this.#options = options;
return this;
}
run(strategy, promises, { concurrency = Number.POSITIVE_INFINITY } = {}) {
if (strategy === "seq") {
return hookSeq(promises);
}
if (strategy === "first") {
return hookFirst(promises, this.#options.nullCheck);
}
if (strategy === "parallel") {
return hookParallel(promises, concurrency);
}
throw new Error(`${strategy} not implemented`);
}
};
function isPromiseRejectedResult(result) {
return result.status === "rejected";
}
// src/errors.ts
var ValidationPluginError = class extends Error {
};
function createPlugin(factory) {
return (options = {}) => {
return factory(options);
};
}
var pluginCore = createPlugin((options) => {
const { fileManager, pluginManager, resolvePath, resolveName, logger } = options;
return {
name: "core",
options,
key: ["core"],
context() {
return {
get config() {
return options.config;
},
get plugins() {
return options.getPlugins();
},
get plugin() {
return options.plugin;
},
logger,
fileManager,
pluginManager,
async addFile(...files) {
const resolvedFiles = await fileManager.add(...files);
if (!Array.isArray(resolvedFiles)) {
return [resolvedFiles];
}
return resolvedFiles;
},
resolvePath,
resolveName
};
},
resolvePath(baseName) {
const root = path3__default.default.resolve(options.config.root, options.config.output.path);
return path3__default.default.resolve(root, baseName);
},
resolveName(name) {
return name;
}
};
});
// src/PluginManager.ts
var PluginManager = class {
plugins = /* @__PURE__ */ new Set();
fileManager;
events = new chunkMCNA6SYG_cjs.EventEmitter();
config;
executed = [];
logger;
options;
#core;
#usedPluginNames = {};
#promiseManager;
constructor(config, options) {
this.config = config;
this.options = options;
this.logger = options.logger;
this.fileManager = new chunkQR7CQIA3_cjs.FileManager();
this.#promiseManager = new PromiseManager({
nullCheck: (state) => !!state?.result
});
const core = pluginCore({
config,
logger: this.logger,
pluginManager: this,
fileManager: this.fileManager,
resolvePath: this.resolvePath.bind(this),
resolveName: this.resolveName.bind(this),
getPlugins: this.#getSortedPlugins.bind(this)
});
this.#core = this.#parse(core, this, core.context.call(null));
[this.#core, ...config.plugins || []].forEach((plugin) => {
const parsedPlugin = this.#parse(plugin, this, this.#core.context);
this.plugins.add(parsedPlugin);
});
return this;
}
getFile({ name, mode, extname, pluginKey, options }) {
const baseName = `${name}${extname}`;
const path4 = this.resolvePath({ baseName, mode, pluginKey, options });
if (!path4) {
throw new Error(`Filepath should be defined for resolvedName "${name}" and pluginKey [${JSON.stringify(pluginKey)}]`);
}
return {
path: path4,
baseName,
meta: {
pluginKey
},
sources: []
};
}
resolvePath = (params) => {
if (params.pluginKey) {
const paths = this.hookForPluginSync({
pluginKey: params.pluginKey,
hookName: "resolvePath",
parameters: [params.baseName, params.mode, params.options],
message: `Resolving path '${params.baseName}'`
});
if (paths && paths?.length > 1) {
this.logger.emit("debug", {
date: /* @__PURE__ */ new Date(),
logs: [
`Cannot return a path where the 'pluginKey' ${params.pluginKey ? JSON.stringify(params.pluginKey) : '"'} is not unique enough
Paths: ${JSON.stringify(paths, void 0, 2)}
Falling back on the first item.
`
]
});
}
return paths?.at(0);
}
return this.hookFirstSync({
hookName: "resolvePath",
parameters: [params.baseName, params.mode, params.options],
message: `Resolving path '${params.baseName}'`
}).result;
};
//TODO refactor by using the order of plugins and the cache of the fileManager instead of guessing and recreating the name/path
resolveName = (params) => {
if (params.pluginKey) {
const names = this.hookForPluginSync({
pluginKey: params.pluginKey,
hookName: "resolveName",
parameters: [chunkBHSTNFNQ_cjs.trim(params.name), params.type],
message: `Resolving name '${params.name}' and type '${params.type}'`
});
if (names && names?.length > 1) {
this.logger.emit("debug", {
date: /* @__PURE__ */ new Date(),
logs: [
`Cannot return a name where the 'pluginKey' ${params.pluginKey ? JSON.stringify(params.pluginKey) : '"'} is not unique enough
Names: ${JSON.stringify(names, void 0, 2)}
Falling back on the first item.
`
]
});
}
return chunkBHSTNFNQ_cjs.transformReservedWord(names?.at(0) || params.name);
}
const name = this.hookFirstSync({
hookName: "resolveName",
parameters: [chunkBHSTNFNQ_cjs.trim(params.name), params.type],
message: `Resolving name '${params.name}' and type '${params.type}'`
}).result;
return chunkBHSTNFNQ_cjs.transformReservedWord(name);
};
/**
* Instead of calling `pluginManager.events.on` you can use `pluginManager.on`. This one also has better types.
*/
on(eventName, handler) {
this.events.on(eventName, handler);
}
/**
* Run a specific hookName for plugin x.
*/
async hookForPlugin({
pluginKey,
hookName,
parameters,
message
}) {
const plugins = this.getPluginsByKey(hookName, pluginKey);
this.logger.emit("progress_start", { id: hookName, size: plugins.length, message: "Running plugins..." });
const items = [];
for (const plugin of plugins) {
const result = await this.#execute({
strategy: "hookFirst",
hookName,
parameters,
plugin,
message
});
if (result !== void 0 && result !== null) {
items.push(result);
}
}
this.logger.emit("progress_stop", { id: hookName });
return items;
}
/**
* Run a specific hookName for plugin x.
*/
hookForPluginSync({
pluginKey,
hookName,
parameters,
message
}) {
const plugins = this.getPluginsByKey(hookName, pluginKey);
const result = plugins.map((plugin) => {
return this.#executeSync({
strategy: "hookFirst",
hookName,
parameters,
plugin,
message
});
}).filter(Boolean);
return result;
}
/**
* First non-null result stops and will return it's value.
*/
async hookFirst({
hookName,
parameters,
skipped,
message
}) {
const plugins = this.#getSortedPlugins(hookName).filter((plugin) => {
return skipped ? skipped.has(plugin) : true;
});
this.logger.emit("progress_start", { id: hookName, size: plugins.length });
const promises = plugins.map((plugin) => {
return async () => {
const value = await this.#execute({
strategy: "hookFirst",
hookName,
parameters,
plugin,
message
});
return Promise.resolve({
plugin,
result: value
});
};
});
const result = await this.#promiseManager.run("first", promises);
this.logger.emit("progress_stop", { id: hookName });
return result;
}
/**
* First non-null result stops and will return it's value.
*/
hookFirstSync({
hookName,
parameters,
skipped,
message
}) {
let parseResult = null;
const plugins = this.#getSortedPlugins(hookName).filter((plugin) => {
return skipped ? skipped.has(plugin) : true;
});
for (const plugin of plugins) {
parseResult = {
result: this.#executeSync({
strategy: "hookFirst",
hookName,
parameters,
plugin,
message
}),
plugin
};
if (parseResult?.result != null) {
break;
}
}
return parseResult;
}
/**
* Run all plugins in parallel(order will be based on `this.plugin` and if `pre` or `post` is set).
*/
async hookParallel({
hookName,
parameters,
message
}) {
const plugins = this.#getSortedPlugins(hookName);
this.logger.emit("progress_start", { id: hookName, size: plugins.length });
const promises = plugins.map((plugin) => {
return () => this.#execute({
strategy: "hookParallel",
hookName,
parameters,
plugin,
message
});
});
const results = await this.#promiseManager.run("parallel", promises, { concurrency: this.options.concurrency });
results.forEach((result, index) => {
if (isPromiseRejectedResult(result)) {
const plugin = this.#getSortedPlugins(hookName)[index];
this.#catcher(result.reason, plugin, hookName);
}
});
this.logger.emit("progress_stop", { id: hookName });
return results.filter((result) => result.status === "fulfilled").map((result) => result.value);
}
/**
* Chains plugins
*/
async hookSeq({
hookName,
parameters,
message
}) {
const plugins = this.#getSortedPlugins(hookName);
this.logger.emit("progress_start", { id: hookName, size: plugins.length });
const promises = plugins.map((plugin) => {
return () => this.#execute({
strategy: "hookSeq",
hookName,
parameters,
plugin,
message
});
});
await this.#promiseManager.run("seq", promises);
this.logger.emit("progress_stop", { id: hookName });
}
#getSortedPlugins(hookName) {
const plugins = [...this.plugins].filter((plugin) => plugin.name !== "core");
if (hookName) {
return plugins.filter((plugin) => hookName in plugin);
}
return plugins.map((plugin) => {
if (plugin.pre) {
const isValid = plugin.pre.every((pluginName) => plugins.find((pluginToFind) => pluginToFind.name === pluginName));
if (!isValid) {
throw new ValidationPluginError(`This plugin has a pre set that is not valid(${JSON.stringify(plugin.pre, void 0, 2)})`);
}
}
return plugin;
}).sort((a, b) => {
if (b.pre?.includes(a.name)) {
return 1;
}
if (b.post?.includes(a.name)) {
return -1;
}
return 0;
});
}
getPluginByKey(pluginKey) {
const plugins = [...this.plugins];
const [searchPluginName] = pluginKey;
return plugins.find((item) => {
const [name] = item.key;
return name === searchPluginName;
});
}
getPluginsByKey(hookName, pluginKey) {
const plugins = [...this.plugins];
const [searchPluginName, searchIdentifier] = pluginKey;
const pluginByPluginName = plugins.filter((plugin) => hookName in plugin).filter((item) => {
const [name, identifier] = item.key;
const identifierCheck = identifier?.toString() === searchIdentifier?.toString();
const nameCheck = name === searchPluginName;
if (searchIdentifier) {
return identifierCheck && nameCheck;
}
return nameCheck;
});
if (!pluginByPluginName?.length) {
const corePlugin = plugins.find((plugin) => plugin.name === "core" && hookName in plugin);
if (corePlugin) {
this.logger.emit("debug", {
date: /* @__PURE__ */ new Date(),
logs: [`No hook '${hookName}' for pluginKey '${JSON.stringify(pluginKey)}' found, falling back on the '@kubb/core' plugin`]
});
} else {
this.logger.emit("debug", {
date: /* @__PURE__ */ new Date(),
logs: [`No hook '${hookName}' for pluginKey '${JSON.stringify(pluginKey)}' found, no fallback found in the '@kubb/core' plugin`]
});
}
return corePlugin ? [corePlugin] : [];
}
return pluginByPluginName;
}
#addExecutedToCallStack(executer) {
if (executer) {
this.events.emit("executed", executer);
this.executed.push(executer);
this.logger.emit("progressed", { id: executer.hookName, message: `${executer.plugin.name}: ${executer.message}` });
}
}
/**
* Run an async plugin hook and return the result.
* @param hookName Name of the plugin hook. Must be either in `PluginHooks` or `OutputPluginValueHooks`.
* @param args Arguments passed to the plugin hook.
* @param plugin The actual pluginObject to run.
*/
// Implementation signature
#execute({
strategy,
hookName,
parameters,
plugin,
message
}) {
const hook = plugin[hookName];
let output;
if (!hook) {
return null;
}
this.events.emit("executing", { strategy, hookName, parameters, plugin, message });
const task = (async () => {
try {
if (typeof hook === "function") {
const result = await Promise.resolve(hook.apply({ ...this.#core.context, plugin }, parameters));
output = result;
this.#addExecutedToCallStack({
parameters,
output,
strategy,
hookName,
plugin,
message
});
return result;
}
output = hook;
this.#addExecutedToCallStack({
parameters,
output,
strategy,
hookName,
plugin,
message
});
return hook;
} catch (e) {
this.#catcher(e, plugin, hookName);
return null;
}
})();
return task;
}
/**
* Run a sync plugin hook and return the result.
* @param hookName Name of the plugin hook. Must be in `PluginHooks`.
* @param args Arguments passed to the plugin hook.
* @param plugin The acutal plugin
* @param replaceContext When passed, the plugin context can be overridden.
*/
#executeSync({
strategy,
hookName,
parameters,
plugin,
message
}) {
const hook = plugin[hookName];
let output;
if (!hook) {
return null;
}
this.events.emit("executing", { strategy, hookName, parameters, plugin, message });
try {
if (typeof hook === "function") {
const fn = hook.apply({ ...this.#core.context, plugin }, parameters);
output = fn;
this.#addExecutedToCallStack({
parameters,
output,
strategy,
hookName,
plugin,
message
});
return fn;
}
output = hook;
this.#addExecutedToCallStack({
parameters,
output,
strategy,
hookName,
plugin,
message
});
return hook;
} catch (e) {
this.#catcher(e, plugin, hookName);
return null;
}
}
#catcher(cause, plugin, hookName) {
const text = `${cause.message} (plugin: ${plugin?.name || "unknown"}, hook: ${hookName || "unknown"})`;
this.logger.emit("error", text, cause);
this.events.emit("error", cause);
}
#parse(plugin, pluginManager, context) {
const usedPluginNames = pluginManager.#usedPluginNames;
chunkQR7CQIA3_cjs.setUniqueName(plugin.name, usedPluginNames);
const key = [plugin.name, usedPluginNames[plugin.name]].filter(Boolean);
if (plugin.context && typeof plugin.context === "function") {
return {
...plugin,
key,
context: plugin.context.call(context)
};
}
return {
...plugin,
key
};
}
static getDependedPlugins(plugins, dependedPluginNames) {
let pluginNames = [];
if (typeof dependedPluginNames === "string") {
pluginNames = [dependedPluginNames];
} else {
pluginNames = dependedPluginNames;
}
return pluginNames.map((pluginName) => {
const plugin = plugins.find((plugin2) => plugin2.name === pluginName);
if (!plugin) {
throw new ValidationPluginError(`This plugin depends on the ${pluginName} plugin.`);
}
return plugin;
});
}
static get hooks() {
return ["buildStart", "resolvePath", "resolveName", "buildEnd"];
}
};
// src/config.ts
function defineConfig(options) {
return options;
}
function isInputPath(result) {
return !!result && "path" in result?.input;
}
async function setup(options) {
if (options.pluginManager) {
return options.pluginManager;
}
const { config: userConfig, logger = chunkMCNA6SYG_cjs.createLogger() } = options;
if (Array.isArray(userConfig.input)) {
chunkMCNA6SYG_cjs.consola.warn(chunkMCNA6SYG_cjs.colors.yellow("This feature is still under development \u2014 use with caution"));
}
try {
if (isInputPath(userConfig) && !new chunkQR7CQIA3_cjs.URLPath(userConfig.input.path).isURL) {
await chunkE4XLCCPK_cjs.exists(userConfig.input.path);
}
} catch (e) {
if (isInputPath(userConfig)) {
throw new Error(
`Cannot read file/URL defined in \`input.path\` or set with \`kubb generate PATH\` in the CLI of your Kubb config ${userConfig.input.path}`,
{
cause: e
}
);
}
}
const definedConfig = {
root: userConfig.root || process.cwd(),
...userConfig,
output: {
write: true,
barrelType: "named",
extension: {
".ts": ".ts"
},
defaultBanner: "simple",
...userConfig.output
},
plugins: userConfig.plugins
};
if (definedConfig.output.clean) {
await chunkE4XLCCPK_cjs.clean(definedConfig.output.path);
await chunkE4XLCCPK_cjs.clean(path3.join(definedConfig.root, ".kubb"));
}
return new PluginManager(definedConfig, { logger, concurrency: 5 });
}
async function build(options) {
const { files, pluginManager, error } = await safeBuild(options);
if (error) throw error;
return {
files,
pluginManager,
error
};
}
async function safeBuild(options) {
const pluginManager = await setup(options);
const config = pluginManager.config;
try {
pluginManager.events.on("executing", ({ plugin, message }) => {
pluginManager.logger.emit("debug", { date: /* @__PURE__ */ new Date(), logs: [`Executing pluginKey ${plugin.key?.join(".")} | ${message}`] });
});
pluginManager.events.on("executed", ({ plugin, message, output }) => {
pluginManager.logger.emit("debug", {
date: /* @__PURE__ */ new Date(),
logs: [`Executed pluginKey ${plugin.key?.join(".")} | ${message} | ${JSON.stringify(output, void 0, 2)}`]
});
});
await pluginManager.hookParallel({
hookName: "buildStart",
parameters: [config],
message: "buildStart"
});
if (config.output.barrelType) {
const root = path3.resolve(config.root);
const rootPath = path3.resolve(root, config.output.path, "index.ts");
const files2 = await pluginManager.fileManager.getFiles();
const barrelFiles = files2.filter((file) => {
return file.sources.some((source) => source.isIndexable);
});
const rootFile = {
path: rootPath,
baseName: "index.ts",
exports: barrelFiles.flatMap((file) => {
const containsOnlyTypes = file.sources?.every((source) => source.isTypeOnly);
return file.sources?.map((source) => {
if (!file.path || !source.isIndexable) {
return void 0;
}
const plugin = [...pluginManager.plugins].find((item) => {
const meta = file.meta;
return remeda.isDeepEqual(item.key, meta?.pluginKey);
});
const pluginOptions = plugin?.options;
if (!pluginOptions || pluginOptions?.output?.barrelType === false) {
return void 0;
}
return {
name: config.output.barrelType === "all" ? void 0 : [source.name],
path: chunkE4XLCCPK_cjs.getRelativePath(rootPath, file.path),
isTypeOnly: config.output.barrelType === "all" ? containsOnlyTypes : source.isTypeOnly
};
}).filter(Boolean);
}).filter(Boolean),
sources: [],
meta: {}
};
await pluginManager.fileManager.add(rootFile);
}
const files = await pluginManager.fileManager.processFiles({
root: config.root,
extension: config.output.extension,
dryRun: !config.output.write,
logger: pluginManager.logger
});
await pluginManager.hookParallel({ hookName: "buildEnd", message: `Build stopped for ${config.name}` });
await pluginManager.fileManager.clear();
return {
files,
pluginManager
};
} catch (e) {
return {
files: [],
pluginManager,
error: e
};
}
}
// src/BaseGenerator.ts
var BaseGenerator = class {
#options = {};
#context = {};
constructor(options, context) {
if (context) {
this.#context = context;
}
if (options) {
this.#options = options;
}
return this;
}
get options() {
return this.#options;
}
get context() {
return this.#context;
}
set options(options) {
this.#options = { ...this.#options, ...options };
}
};
var EndError = class extends Error {
constructor(value) {
super();
this.value = value;
}
};
var testElement = async (element, tester) => tester(await element);
var finder = async (element) => {
const values = await Promise.all(element);
if (values[1] === true) {
throw new EndError(values[0]);
}
return false;
};
async function pLocate(iterable, tester, {
concurrency = Number.POSITIVE_INFINITY,
preserveOrder = true
} = {}) {
const limit = pLimit2__default.default(concurrency);
const items = [...iterable].map((element) => [element, limit(testElement, element, tester)]);
const checkLimit = pLimit2__default.default(preserveOrder ? 1 : Number.POSITIVE_INFINITY);
try {
await Promise.all(items.map((element) => checkLimit(finder, element)));
} catch (error) {
if (error instanceof EndError) {
return error.value;
}
throw error;
}
}
// ../../node_modules/.pnpm/locate-path@7.2.0/node_modules/locate-path/index.js
var typeMappings = {
directory: "isDirectory",
file: "isFile"
};
function checkType(type) {
if (Object.hasOwnProperty.call(typeMappings, type)) {
return;
}
throw new Error(`Invalid type specified: ${type}`);
}
var matchType = (type, stat) => stat[typeMappings[type]]();
var toPath = (urlOrPath) => urlOrPath instanceof URL ? url.fileURLToPath(urlOrPath) : urlOrPath;
async function locatePath(paths, {
cwd = process2__default.default.cwd(),
type = "file",
allowSymlinks = true,
concurrency,
preserveOrder
} = {}) {
checkType(type);
cwd = toPath(cwd);
const statFunction = allowSymlinks ? fs.promises.stat : fs.promises.lstat;
return pLocate(paths, async (path_) => {
try {
const stat = await statFunction(path3__default.default.resolve(cwd, path_));
return matchType(type, stat);
} catch {
return false;
}
}, { concurrency, preserveOrder });
}
function locatePathSync(paths, {
cwd = process2__default.default.cwd(),
type = "file",
allowSymlinks = true
} = {}) {
checkType(type);
cwd = toPath(cwd);
const statFunction = allowSymlinks ? fs__default.default.statSync : fs__default.default.lstatSync;
for (const path_ of paths) {
try {
const stat = statFunction(path3__default.default.resolve(cwd, path_), {
throwIfNoEntry: false
});
if (!stat) {
continue;
}
if (matchType(type, stat)) {
return path_;
}
} catch {
}
}
}
function toPath2(urlOrPath) {
return urlOrPath instanceof URL ? url.fileURLToPath(urlOrPath) : urlOrPath;
}
// ../../node_modules/.pnpm/find-up@7.0.0/node_modules/find-up/index.js
var findUpStop = Symbol("findUpStop");
async function findUpMultiple(name, options = {}) {
let directory = path3__default.default.resolve(toPath2(options.cwd) ?? "");
const { root } = path3__default.default.parse(directory);
const stopAt = path3__default.default.resolve(directory, toPath2(options.stopAt ?? root));
const limit = options.limit ?? Number.POSITIVE_INFINITY;
const paths = [name].flat();
const runMatcher = async (locateOptions) => {
if (typeof name !== "function") {
return locatePath(paths, locateOptions);
}
const foundPath = await name(locateOptions.cwd);
if (typeof foundPath === "string") {
return locatePath([foundPath], locateOptions);
}
return foundPath;
};
const matches = [];
while (true) {
const foundPath = await runMatcher({ ...options, cwd: directory });
if (foundPath === findUpStop) {
break;
}
if (foundPath) {
matches.push(path3__default.default.resolve(directory, foundPath));
}
if (directory === stopAt || matches.length >= limit) {
break;
}
directory = path3__default.default.dirname(directory);
}
return matches;
}
function findUpMultipleSync(name, options = {}) {
let directory = path3__default.default.resolve(toPath2(options.cwd) ?? "");
const { root } = path3__default.default.parse(directory);
const stopAt = path3__default.default.resolve(directory, toPath2(options.stopAt) ?? root);
const limit = options.limit ?? Number.POSITIVE_INFINITY;
const paths = [name].flat();
const runMatcher = (locateOptions) => {
if (typeof name !== "function") {
return locatePathSync(paths, locateOptions);
}
const foundPath = name(locateOptions.cwd);
if (typeof foundPath === "string") {
return locatePathSync([foundPath], locateOptions);
}
return foundPath;
};
const matches = [];
while (true) {
const foundPath = runMatcher({ ...options, cwd: directory });
if (foundPath === findUpStop) {
break;
}
if (foundPath) {
matches.push(path3__default.default.resolve(directory, foundPath));
}
if (directory === stopAt || matches.length >= limit) {
break;
}
directory = path3__default.default.dirname(directory);
}
return matches;
}
async function findUp(name, options = {}) {
const matches = await findUpMultiple(name, { ...options, limit: 1 });
return matches[0];
}
function findUpSync(name, options = {}) {
const matches = findUpMultipleSync(name, { ...options, limit: 1 });
return matches[0];
}
var PackageManager = class _PackageManager {
static #cache = {};
#cwd;
#SLASHES = /* @__PURE__ */ new Set(["/", "\\"]);
constructor(workspace) {
if (workspace) {
this.#cwd = workspace;
}
return this;
}
set workspace(workspace) {
this.#cwd = workspace;
}
get workspace() {
return this.#cwd;
}
normalizeDirectory(directory) {
if (!this.#SLASHES.has(directory[directory.length - 1])) {
return `${directory}/`;
}
return directory;
}
getLocation(path4) {
let location = path4;
if (this.#cwd) {
const require2 = mod__default.default.createRequire(this.normalizeDirectory(this.#cwd));
location = require2.resolve(path4);
}
return location;
}
async import(path4) {
try {
let location = this.getLocation(path4);
if (os__default.default.platform() === "win32") {
location = url.pathToFileURL(location).href;
}
const module = await import(location);
return module?.default ?? module;
} catch (e) {
console.error(e);
return void 0;
}
}
async getPackageJSON() {
const pkgPath = await findUp(["package.json"], {
cwd: this.#cwd
});
if (!pkgPath) {
return void 0;
}
const json = await chunkE4XLCCPK_cjs.read(pkgPath);
return JSON.parse(json);
}
getPackageJSONSync() {
const pkgPath = findUpSync(["package.json"], {
cwd: this.#cwd
});
if (!pkgPath) {
return void 0;
}
const json = chunkE4XLCCPK_cjs.readSync(pkgPath);
return JSON.parse(json);
}
static setVersion(dependency, version) {
_PackageManager.#cache[dependency] = version;
}
#match(packageJSON, dependency) {
const dependencies = {
...packageJSON["dependencies"] || {},
...packageJSON["devDependencies"] || {}
};
if (typeof dependency === "string" && dependencies[dependency]) {
return dependencies[dependency];
}
const matchedDependency = Object.keys(dependencies).find((dep) => dep.match(dependency));
return matchedDependency ? dependencies[matchedDependency] : void 0;
}
async getVersion(dependency) {
if (typeof dependency === "string" && _PackageManager.#cache[dependency]) {
return _PackageManager.#cache[dependency];
}
const packageJSON = await this.getPackageJSON();
if (!packageJSON) {
return void 0;
}
return this.#match(packageJSON, dependency);
}
getVersionSync(dependency) {
if (typeof dependency === "string" && _PackageManager.#cache[dependency]) {
return _PackageManager.#cache[dependency];
}
const packageJSON = this.getPackageJSONSync();
if (!packageJSON) {
return void 0;
}
return this.#match(packageJSON, dependency);
}
async isValid(dependency, version) {
const packageVersion = await this.getVersion(dependency);
if (!packageVersion) {
return false;
}
if (packageVersion === version) {
return true;
}
const semVer = semver.coerce(packageVersion);
if (!semVer) {
throw new Error(`${packageVersion} is not valid`);
}
return semver.satisfies(semVer, version);
}
isValidSync(dependency, version) {
const packageVersion = this.getVersionSync(dependency);
if (!packageVersion) {
return false;
}
if (version === "next" && packageVersion === version) {
return true;
}
const semVer = semver.coerce(packageVersion);
if (!semVer) {
return false;
}
return semver.satisfies(semVer, version);
}
};
Object.defineProperty(exports, "FileManager", {
enumerable: true,
get: function () { return chunkQR7CQIA3_cjs.FileManager; }
});
Object.defineProperty(exports, "getDefaultBanner", {
enumerable: true,
get: function () { return chunkQR7CQIA3_cjs.getDefaultBanner; }
});
Object.defineProperty(exports, "getSource", {
enumerable: true,
get: function () { return chunkQR7CQIA3_cjs.getSource; }
});
exports.BaseGenerator = BaseGenerator;
exports.PackageManager = PackageManager;
exports.PluginManager = PluginManager;
exports.PromiseManager = PromiseManager;
exports.build = build;
exports.createPlugin = createPlugin;
exports.default = build;
exports.defineConfig = defineConfig;
exports.isInputPath = isInputPath;
exports.safeBuild = safeBuild;
exports.setup = setup;
//# sourceMappingURL=index.cjs.map
//# sourceMappingURL=index.cjs.map