feat(lib-core): biblioteca atomica @pulse-libs/core v1.0.0-beta.1
Esta commit conteudo a estrutura atomica completa:
- types: Result<T,E>, AsyncState<T>, Paginated<T>, SortConfig<T>
- utils: date, str, num, cn, debounce, throttle, storage, arr, obj
- validators: Zod schemas — email, password, uuid, url, phone, CPF/CNPJ, sanitizedStr, safeParse
- hooks: useToggle, useAsync, useDebounce, useLocalStorage, useMedia, useInterval, useOnClickOutside, useClipboard, useFetch
- components: Button, Input, Alert, Card, Spinner (atomic design pattern)
- build: tsup v8 ESM+CJS + DTS + sourcemaps — 0 erros
- tests: 57 testes 100% usuarios
- docker: multi-stage Dockerfile (node 20-alpine)
- config: vitest, tsup, tsconfig strict, .npmignore
Filosofia atomica:/utils ← /types ← /validators ← /hooks ← /components
Build: npm run build | Test: npm test | Publish: npm publish
🤖 Generated with Pulse (openclaw + nova-self-improver)
This commit is contained in:
+21
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright © 2021 EGOIST (https://github.com/sponsors/egoist)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
**💛 You can help the author become a full-time open-source maintainer by [sponsoring him on GitHub](https://github.com/sponsors/egoist).**
|
||||
|
||||
---
|
||||
|
||||
# bundle-require
|
||||
|
||||
[](https://npm.im/bundle-require) [](https://npm.im/bundle-require) [](https://www.jsdocs.io/package/bundle-require)
|
||||
|
||||
## Use Case
|
||||
|
||||
Projects like [Vite](https://vitejs.dev) need to load config files provided by the user, but you can't do it with just `require()` because it's not necessarily a CommonJS module, it could also be a `.mjs` or even be written in TypeScript, and that's where the `bundle-require` package comes in, it loads the config file regardless what module format it is.
|
||||
|
||||
## How it works
|
||||
|
||||
- Bundle your file with esbuild, `node_modules` are excluded because it's problematic to try to bundle it
|
||||
- `__filename`, `__dirname` and `import.meta.url` are replaced with source file's value instead of the one from the temporary output file
|
||||
- Output file in `esm` format if possible (for `.ts`, `.js` input files)
|
||||
- Load output file with `import()` if possible
|
||||
- Return the loaded module and its dependencies (imported files)
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
npm i bundle-require esbuild
|
||||
```
|
||||
|
||||
`esbuild` is a peer dependency.
|
||||
|
||||
## Usage
|
||||
|
||||
```ts
|
||||
import { bundleRequire } from 'bundle-require'
|
||||
|
||||
const { mod } = await bundleRequire({
|
||||
filepath: './project/vite.config.ts',
|
||||
})
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
https://www.jsdocs.io/package/bundle-require
|
||||
|
||||
## Projects Using bundle-require
|
||||
|
||||
Projects that use **bundle-require**:
|
||||
|
||||
- [VuePress](https://github.com/vuejs/vuepress): :memo: Minimalistic Vue-powered static site generator.
|
||||
|
||||
## Sponsors
|
||||
|
||||
[](https://github.com/sponsors/egoist)
|
||||
|
||||
## License
|
||||
|
||||
MIT © [EGOIST](https://github.com/sponsors/egoist)
|
||||
+297
@@ -0,0 +1,297 @@
|
||||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// src/index.ts
|
||||
var src_exports = {};
|
||||
__export(src_exports, {
|
||||
JS_EXT_RE: () => JS_EXT_RE,
|
||||
bundleRequire: () => bundleRequire,
|
||||
dynamicImport: () => dynamicImport,
|
||||
externalPlugin: () => externalPlugin,
|
||||
injectFileScopePlugin: () => injectFileScopePlugin,
|
||||
loadTsConfig: () => import_load_tsconfig.loadTsConfig,
|
||||
match: () => match,
|
||||
tsconfigPathsToRegExp: () => tsconfigPathsToRegExp
|
||||
});
|
||||
module.exports = __toCommonJS(src_exports);
|
||||
var import_fs2 = __toESM(require("fs"), 1);
|
||||
var import_path2 = __toESM(require("path"), 1);
|
||||
var import_url = require("url");
|
||||
var import_esbuild = require("esbuild");
|
||||
var import_load_tsconfig = require("load-tsconfig");
|
||||
|
||||
// src/utils.ts
|
||||
var import_fs = __toESM(require("fs"), 1);
|
||||
var import_path = __toESM(require("path"), 1);
|
||||
var getPkgType = () => {
|
||||
try {
|
||||
const pkg = JSON.parse(
|
||||
import_fs.default.readFileSync(import_path.default.resolve("package.json"), "utf-8")
|
||||
);
|
||||
return pkg.type;
|
||||
} catch (error) {
|
||||
}
|
||||
};
|
||||
function guessFormat(inputFile) {
|
||||
if (!usingDynamicImport)
|
||||
return "cjs";
|
||||
const ext = import_path.default.extname(inputFile);
|
||||
const type = getPkgType();
|
||||
if (ext === ".js") {
|
||||
return type === "module" ? "esm" : "cjs";
|
||||
} else if (ext === ".ts" || ext === ".mts") {
|
||||
return "esm";
|
||||
} else if (ext === ".mjs") {
|
||||
return "esm";
|
||||
}
|
||||
return "cjs";
|
||||
}
|
||||
var usingDynamicImport = typeof jest === "undefined";
|
||||
var dynamicImport = async (id, { format }) => {
|
||||
const fn = format === "esm" ? (file) => import(file) : false ? createRequire(import_meta.url) : require;
|
||||
return fn(id);
|
||||
};
|
||||
var getRandomId = () => {
|
||||
return Math.random().toString(36).substring(2, 15);
|
||||
};
|
||||
|
||||
// src/index.ts
|
||||
var DIRNAME_VAR_NAME = "__injected_dirname__";
|
||||
var FILENAME_VAR_NAME = "__injected_filename__";
|
||||
var IMPORT_META_URL_VAR_NAME = "__injected_import_meta_url__";
|
||||
var JS_EXT_RE = /\.([mc]?[tj]s|[tj]sx)$/;
|
||||
var PATH_NODE_MODULES_RE = /[\/\\]node_modules[\/\\]/;
|
||||
function inferLoader(ext) {
|
||||
if (ext === ".mjs" || ext === ".cjs")
|
||||
return "js";
|
||||
if (ext === ".mts" || ext === ".cts")
|
||||
return "ts";
|
||||
return ext.slice(1);
|
||||
}
|
||||
var defaultReadFile = (filepath) => import_fs2.default.readFileSync(filepath, "utf-8");
|
||||
var defaultGetOutputFile = (filepath, format) => filepath.replace(
|
||||
JS_EXT_RE,
|
||||
`.bundled_${getRandomId()}.${format === "esm" ? "mjs" : "cjs"}`
|
||||
);
|
||||
var tsconfigPathsToRegExp = (paths) => {
|
||||
return Object.keys(paths || {}).map((key) => {
|
||||
return new RegExp(`^${key.replace(/\*/, ".*")}$`);
|
||||
});
|
||||
};
|
||||
var match = (id, patterns) => {
|
||||
if (!patterns)
|
||||
return false;
|
||||
return patterns.some((p) => {
|
||||
if (p instanceof RegExp) {
|
||||
return p.test(id);
|
||||
}
|
||||
return id === p || id.startsWith(p + "/");
|
||||
});
|
||||
};
|
||||
var externalPlugin = ({
|
||||
external,
|
||||
notExternal,
|
||||
externalNodeModules = true
|
||||
} = {}) => {
|
||||
return {
|
||||
name: "bundle-require:external",
|
||||
setup(ctx) {
|
||||
ctx.onResolve({ filter: /.*/ }, async (args) => {
|
||||
if (match(args.path, external)) {
|
||||
return {
|
||||
external: true
|
||||
};
|
||||
}
|
||||
if (match(args.path, notExternal)) {
|
||||
return;
|
||||
}
|
||||
if (externalNodeModules && args.path.match(PATH_NODE_MODULES_RE)) {
|
||||
const resolved = args.path[0] === "." ? import_path2.default.resolve(args.resolveDir, args.path) : args.path;
|
||||
return {
|
||||
path: (0, import_url.pathToFileURL)(resolved).toString(),
|
||||
external: true
|
||||
};
|
||||
}
|
||||
if (args.path[0] === "." || import_path2.default.isAbsolute(args.path)) {
|
||||
return;
|
||||
}
|
||||
return {
|
||||
external: true
|
||||
};
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
||||
var injectFileScopePlugin = ({
|
||||
readFile = defaultReadFile
|
||||
} = {}) => {
|
||||
return {
|
||||
name: "bundle-require:inject-file-scope",
|
||||
setup(ctx) {
|
||||
ctx.initialOptions.define = {
|
||||
...ctx.initialOptions.define,
|
||||
__dirname: DIRNAME_VAR_NAME,
|
||||
__filename: FILENAME_VAR_NAME,
|
||||
"import.meta.url": IMPORT_META_URL_VAR_NAME
|
||||
};
|
||||
ctx.onLoad({ filter: JS_EXT_RE }, (args) => {
|
||||
const contents = readFile(args.path);
|
||||
const injectLines = [
|
||||
`const ${FILENAME_VAR_NAME} = ${JSON.stringify(args.path)};`,
|
||||
`const ${DIRNAME_VAR_NAME} = ${JSON.stringify(
|
||||
import_path2.default.dirname(args.path)
|
||||
)};`,
|
||||
`const ${IMPORT_META_URL_VAR_NAME} = ${JSON.stringify(
|
||||
(0, import_url.pathToFileURL)(args.path).href
|
||||
)};`
|
||||
];
|
||||
return {
|
||||
contents: injectLines.join("") + contents,
|
||||
loader: inferLoader(import_path2.default.extname(args.path))
|
||||
};
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
||||
function bundleRequire(options) {
|
||||
return new Promise((resolve, reject) => {
|
||||
var _a, _b, _c, _d, _e;
|
||||
if (!JS_EXT_RE.test(options.filepath)) {
|
||||
throw new Error(`${options.filepath} is not a valid JS file`);
|
||||
}
|
||||
const preserveTemporaryFile = (_a = options.preserveTemporaryFile) != null ? _a : !!process.env.BUNDLE_REQUIRE_PRESERVE;
|
||||
const cwd = options.cwd || process.cwd();
|
||||
const format = (_b = options.format) != null ? _b : guessFormat(options.filepath);
|
||||
const tsconfig = options.tsconfig === false ? void 0 : typeof options.tsconfig === "string" || !options.tsconfig ? (0, import_load_tsconfig.loadTsConfig)(cwd, options.tsconfig) : { data: options.tsconfig, path: void 0 };
|
||||
const resolvePaths = tsconfigPathsToRegExp(
|
||||
((_c = tsconfig == null ? void 0 : tsconfig.data.compilerOptions) == null ? void 0 : _c.paths) || {}
|
||||
);
|
||||
const extractResult = async (result) => {
|
||||
if (!result.outputFiles) {
|
||||
throw new Error(`[bundle-require] no output files`);
|
||||
}
|
||||
const { text } = result.outputFiles[0];
|
||||
const getOutputFile = options.getOutputFile || defaultGetOutputFile;
|
||||
const outfile = getOutputFile(options.filepath, format);
|
||||
await import_fs2.default.promises.writeFile(outfile, text, "utf8");
|
||||
let mod;
|
||||
const req = options.require || dynamicImport;
|
||||
try {
|
||||
mod = await req(
|
||||
format === "esm" ? (0, import_url.pathToFileURL)(outfile).href : outfile,
|
||||
{ format }
|
||||
);
|
||||
} finally {
|
||||
if (!preserveTemporaryFile) {
|
||||
await import_fs2.default.promises.unlink(outfile);
|
||||
}
|
||||
}
|
||||
return {
|
||||
mod,
|
||||
dependencies: result.metafile ? Object.keys(result.metafile.inputs) : []
|
||||
};
|
||||
};
|
||||
const { watch: watchMode, ...restEsbuildOptions } = options.esbuildOptions || {};
|
||||
const esbuildOptions = {
|
||||
...restEsbuildOptions,
|
||||
entryPoints: [options.filepath],
|
||||
absWorkingDir: cwd,
|
||||
outfile: "out.js",
|
||||
format,
|
||||
platform: "node",
|
||||
sourcemap: "inline",
|
||||
bundle: true,
|
||||
metafile: true,
|
||||
write: false,
|
||||
...(tsconfig == null ? void 0 : tsconfig.path) ? { tsconfig: tsconfig.path } : { tsconfigRaw: (tsconfig == null ? void 0 : tsconfig.data) || {} },
|
||||
plugins: [
|
||||
...((_d = options.esbuildOptions) == null ? void 0 : _d.plugins) || [],
|
||||
externalPlugin({
|
||||
external: options.external,
|
||||
notExternal: [...options.notExternal || [], ...resolvePaths],
|
||||
externalNodeModules: (_e = options.externalNodeModules) != null ? _e : !options.filepath.match(PATH_NODE_MODULES_RE)
|
||||
}),
|
||||
injectFileScopePlugin({
|
||||
readFile: options.readFile
|
||||
})
|
||||
]
|
||||
};
|
||||
const run = async () => {
|
||||
if (!(watchMode || options.onRebuild)) {
|
||||
const result = await (0, import_esbuild.build)(esbuildOptions);
|
||||
resolve(await extractResult(result));
|
||||
} else {
|
||||
const rebuildCallback = typeof watchMode === "object" && typeof watchMode.onRebuild === "function" ? watchMode.onRebuild : async (error, result) => {
|
||||
var _a2, _b2;
|
||||
if (error) {
|
||||
(_a2 = options.onRebuild) == null ? void 0 : _a2.call(options, { err: error });
|
||||
}
|
||||
if (result) {
|
||||
(_b2 = options.onRebuild) == null ? void 0 : _b2.call(options, await extractResult(result));
|
||||
}
|
||||
};
|
||||
const onRebuildPlugin = () => {
|
||||
return {
|
||||
name: "bundle-require:on-rebuild",
|
||||
setup(ctx2) {
|
||||
let count = 0;
|
||||
ctx2.onEnd(async (result) => {
|
||||
if (count++ === 0) {
|
||||
if (result.errors.length === 0)
|
||||
resolve(await extractResult(result));
|
||||
} else {
|
||||
if (result.errors.length > 0) {
|
||||
return rebuildCallback(
|
||||
{ errors: result.errors, warnings: result.warnings },
|
||||
null
|
||||
);
|
||||
}
|
||||
if (result) {
|
||||
rebuildCallback(null, result);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
||||
esbuildOptions.plugins.push(onRebuildPlugin());
|
||||
const ctx = await (0, import_esbuild.context)(esbuildOptions);
|
||||
await ctx.watch();
|
||||
}
|
||||
};
|
||||
run().catch(reject);
|
||||
});
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
JS_EXT_RE,
|
||||
bundleRequire,
|
||||
dynamicImport,
|
||||
externalPlugin,
|
||||
injectFileScopePlugin,
|
||||
loadTsConfig,
|
||||
match,
|
||||
tsconfigPathsToRegExp
|
||||
});
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
import { BuildFailure, BuildResult, BuildOptions, TsconfigRaw, Plugin } from 'esbuild';
|
||||
export { loadTsConfig } from 'load-tsconfig';
|
||||
|
||||
/**
|
||||
* Dynamically import files.
|
||||
*
|
||||
* As a temporary workaround for Jest's lack of stable ESM support, we fallback to require
|
||||
* if we're in a Jest environment.
|
||||
* See https://github.com/vitejs/vite/pull/5197#issuecomment-938054077
|
||||
*
|
||||
* @param file File path to import.
|
||||
*/
|
||||
declare const dynamicImport: RequireFunction;
|
||||
|
||||
declare const JS_EXT_RE: RegExp;
|
||||
|
||||
type RequireFunction = (outfile: string, ctx: {
|
||||
format: "cjs" | "esm";
|
||||
}) => any;
|
||||
type GetOutputFile = (filepath: string, format: "esm" | "cjs") => string;
|
||||
type RebuildCallback = (error: Pick<BuildFailure, "errors" | "warnings"> | null, result: BuildResult | null) => void;
|
||||
type ReadFile = (filepath: string) => string;
|
||||
interface Options {
|
||||
cwd?: string;
|
||||
/**
|
||||
* The filepath to bundle and require
|
||||
*/
|
||||
filepath: string;
|
||||
/**
|
||||
* The `require` function that is used to load the output file
|
||||
* Default to the global `require` function
|
||||
* This function can be asynchronous, i.e. returns a Promise
|
||||
*/
|
||||
require?: RequireFunction;
|
||||
/**
|
||||
* esbuild options
|
||||
*
|
||||
*/
|
||||
esbuildOptions?: BuildOptions & {
|
||||
/**
|
||||
* @deprecated `esbuildOptions.watch` is deprecated, use `onRebuild` instead
|
||||
*/
|
||||
watch?: boolean | {
|
||||
onRebuild?: RebuildCallback;
|
||||
};
|
||||
};
|
||||
/**
|
||||
* Get the path to the output file
|
||||
* By default we simply replace the extension with `.bundled_{randomId}.js`
|
||||
*/
|
||||
getOutputFile?: GetOutputFile;
|
||||
/**
|
||||
* Enable watching and call the callback after each rebuild
|
||||
*/
|
||||
onRebuild?: (ctx: {
|
||||
err?: Pick<BuildFailure, "errors" | "warnings">;
|
||||
mod?: any;
|
||||
dependencies?: string[];
|
||||
}) => void;
|
||||
/** External packages */
|
||||
external?: (string | RegExp)[];
|
||||
/** Not external packages */
|
||||
notExternal?: (string | RegExp)[];
|
||||
/**
|
||||
* Automatically mark node_modules as external
|
||||
* @default true - `false` when `filepath` is in node_modules
|
||||
*/
|
||||
externalNodeModules?: boolean;
|
||||
/**
|
||||
* A custom tsconfig path to read `paths` option
|
||||
*
|
||||
* Set to `false` to disable tsconfig
|
||||
* Or provide a `TsconfigRaw` object
|
||||
*/
|
||||
tsconfig?: string | TsconfigRaw | false;
|
||||
/**
|
||||
* Preserve compiled temporary file for debugging
|
||||
* Default to `process.env.BUNDLE_REQUIRE_PRESERVE`
|
||||
*/
|
||||
preserveTemporaryFile?: boolean;
|
||||
/**
|
||||
* Provide bundle format explicitly
|
||||
* to skip the default format inference
|
||||
*/
|
||||
format?: "cjs" | "esm";
|
||||
readFile?: ReadFile;
|
||||
}
|
||||
|
||||
declare const tsconfigPathsToRegExp: (paths: Record<string, any>) => RegExp[];
|
||||
declare const match: (id: string, patterns?: (string | RegExp)[]) => boolean;
|
||||
/**
|
||||
* An esbuild plugin to mark node_modules as external
|
||||
*/
|
||||
declare const externalPlugin: ({ external, notExternal, externalNodeModules, }?: {
|
||||
external?: (string | RegExp)[] | undefined;
|
||||
notExternal?: (string | RegExp)[] | undefined;
|
||||
externalNodeModules?: boolean | undefined;
|
||||
}) => Plugin;
|
||||
declare const injectFileScopePlugin: ({ readFile, }?: {
|
||||
readFile?: ReadFile | undefined;
|
||||
}) => Plugin;
|
||||
declare function bundleRequire<T = any>(options: Options): Promise<{
|
||||
mod: T;
|
||||
dependencies: string[];
|
||||
}>;
|
||||
|
||||
export { GetOutputFile, JS_EXT_RE, Options, ReadFile, RebuildCallback, RequireFunction, bundleRequire, dynamicImport, externalPlugin, injectFileScopePlugin, match, tsconfigPathsToRegExp };
|
||||
+263
@@ -0,0 +1,263 @@
|
||||
// src/index.ts
|
||||
import fs2 from "fs";
|
||||
import path2 from "path";
|
||||
import { pathToFileURL } from "url";
|
||||
import {
|
||||
build,
|
||||
context
|
||||
} from "esbuild";
|
||||
import { loadTsConfig } from "load-tsconfig";
|
||||
|
||||
// src/utils.ts
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import { createRequire } from "module";
|
||||
var getPkgType = () => {
|
||||
try {
|
||||
const pkg = JSON.parse(
|
||||
fs.readFileSync(path.resolve("package.json"), "utf-8")
|
||||
);
|
||||
return pkg.type;
|
||||
} catch (error) {
|
||||
}
|
||||
};
|
||||
function guessFormat(inputFile) {
|
||||
if (!usingDynamicImport)
|
||||
return "cjs";
|
||||
const ext = path.extname(inputFile);
|
||||
const type = getPkgType();
|
||||
if (ext === ".js") {
|
||||
return type === "module" ? "esm" : "cjs";
|
||||
} else if (ext === ".ts" || ext === ".mts") {
|
||||
return "esm";
|
||||
} else if (ext === ".mjs") {
|
||||
return "esm";
|
||||
}
|
||||
return "cjs";
|
||||
}
|
||||
var usingDynamicImport = typeof jest === "undefined";
|
||||
var dynamicImport = async (id, { format }) => {
|
||||
const fn = format === "esm" ? (file) => import(file) : true ? createRequire(import.meta.url) : __require;
|
||||
return fn(id);
|
||||
};
|
||||
var getRandomId = () => {
|
||||
return Math.random().toString(36).substring(2, 15);
|
||||
};
|
||||
|
||||
// src/index.ts
|
||||
var DIRNAME_VAR_NAME = "__injected_dirname__";
|
||||
var FILENAME_VAR_NAME = "__injected_filename__";
|
||||
var IMPORT_META_URL_VAR_NAME = "__injected_import_meta_url__";
|
||||
var JS_EXT_RE = /\.([mc]?[tj]s|[tj]sx)$/;
|
||||
var PATH_NODE_MODULES_RE = /[\/\\]node_modules[\/\\]/;
|
||||
function inferLoader(ext) {
|
||||
if (ext === ".mjs" || ext === ".cjs")
|
||||
return "js";
|
||||
if (ext === ".mts" || ext === ".cts")
|
||||
return "ts";
|
||||
return ext.slice(1);
|
||||
}
|
||||
var defaultReadFile = (filepath) => fs2.readFileSync(filepath, "utf-8");
|
||||
var defaultGetOutputFile = (filepath, format) => filepath.replace(
|
||||
JS_EXT_RE,
|
||||
`.bundled_${getRandomId()}.${format === "esm" ? "mjs" : "cjs"}`
|
||||
);
|
||||
var tsconfigPathsToRegExp = (paths) => {
|
||||
return Object.keys(paths || {}).map((key) => {
|
||||
return new RegExp(`^${key.replace(/\*/, ".*")}$`);
|
||||
});
|
||||
};
|
||||
var match = (id, patterns) => {
|
||||
if (!patterns)
|
||||
return false;
|
||||
return patterns.some((p) => {
|
||||
if (p instanceof RegExp) {
|
||||
return p.test(id);
|
||||
}
|
||||
return id === p || id.startsWith(p + "/");
|
||||
});
|
||||
};
|
||||
var externalPlugin = ({
|
||||
external,
|
||||
notExternal,
|
||||
externalNodeModules = true
|
||||
} = {}) => {
|
||||
return {
|
||||
name: "bundle-require:external",
|
||||
setup(ctx) {
|
||||
ctx.onResolve({ filter: /.*/ }, async (args) => {
|
||||
if (match(args.path, external)) {
|
||||
return {
|
||||
external: true
|
||||
};
|
||||
}
|
||||
if (match(args.path, notExternal)) {
|
||||
return;
|
||||
}
|
||||
if (externalNodeModules && args.path.match(PATH_NODE_MODULES_RE)) {
|
||||
const resolved = args.path[0] === "." ? path2.resolve(args.resolveDir, args.path) : args.path;
|
||||
return {
|
||||
path: pathToFileURL(resolved).toString(),
|
||||
external: true
|
||||
};
|
||||
}
|
||||
if (args.path[0] === "." || path2.isAbsolute(args.path)) {
|
||||
return;
|
||||
}
|
||||
return {
|
||||
external: true
|
||||
};
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
||||
var injectFileScopePlugin = ({
|
||||
readFile = defaultReadFile
|
||||
} = {}) => {
|
||||
return {
|
||||
name: "bundle-require:inject-file-scope",
|
||||
setup(ctx) {
|
||||
ctx.initialOptions.define = {
|
||||
...ctx.initialOptions.define,
|
||||
__dirname: DIRNAME_VAR_NAME,
|
||||
__filename: FILENAME_VAR_NAME,
|
||||
"import.meta.url": IMPORT_META_URL_VAR_NAME
|
||||
};
|
||||
ctx.onLoad({ filter: JS_EXT_RE }, (args) => {
|
||||
const contents = readFile(args.path);
|
||||
const injectLines = [
|
||||
`const ${FILENAME_VAR_NAME} = ${JSON.stringify(args.path)};`,
|
||||
`const ${DIRNAME_VAR_NAME} = ${JSON.stringify(
|
||||
path2.dirname(args.path)
|
||||
)};`,
|
||||
`const ${IMPORT_META_URL_VAR_NAME} = ${JSON.stringify(
|
||||
pathToFileURL(args.path).href
|
||||
)};`
|
||||
];
|
||||
return {
|
||||
contents: injectLines.join("") + contents,
|
||||
loader: inferLoader(path2.extname(args.path))
|
||||
};
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
||||
function bundleRequire(options) {
|
||||
return new Promise((resolve, reject) => {
|
||||
var _a, _b, _c, _d, _e;
|
||||
if (!JS_EXT_RE.test(options.filepath)) {
|
||||
throw new Error(`${options.filepath} is not a valid JS file`);
|
||||
}
|
||||
const preserveTemporaryFile = (_a = options.preserveTemporaryFile) != null ? _a : !!process.env.BUNDLE_REQUIRE_PRESERVE;
|
||||
const cwd = options.cwd || process.cwd();
|
||||
const format = (_b = options.format) != null ? _b : guessFormat(options.filepath);
|
||||
const tsconfig = options.tsconfig === false ? void 0 : typeof options.tsconfig === "string" || !options.tsconfig ? loadTsConfig(cwd, options.tsconfig) : { data: options.tsconfig, path: void 0 };
|
||||
const resolvePaths = tsconfigPathsToRegExp(
|
||||
((_c = tsconfig == null ? void 0 : tsconfig.data.compilerOptions) == null ? void 0 : _c.paths) || {}
|
||||
);
|
||||
const extractResult = async (result) => {
|
||||
if (!result.outputFiles) {
|
||||
throw new Error(`[bundle-require] no output files`);
|
||||
}
|
||||
const { text } = result.outputFiles[0];
|
||||
const getOutputFile = options.getOutputFile || defaultGetOutputFile;
|
||||
const outfile = getOutputFile(options.filepath, format);
|
||||
await fs2.promises.writeFile(outfile, text, "utf8");
|
||||
let mod;
|
||||
const req = options.require || dynamicImport;
|
||||
try {
|
||||
mod = await req(
|
||||
format === "esm" ? pathToFileURL(outfile).href : outfile,
|
||||
{ format }
|
||||
);
|
||||
} finally {
|
||||
if (!preserveTemporaryFile) {
|
||||
await fs2.promises.unlink(outfile);
|
||||
}
|
||||
}
|
||||
return {
|
||||
mod,
|
||||
dependencies: result.metafile ? Object.keys(result.metafile.inputs) : []
|
||||
};
|
||||
};
|
||||
const { watch: watchMode, ...restEsbuildOptions } = options.esbuildOptions || {};
|
||||
const esbuildOptions = {
|
||||
...restEsbuildOptions,
|
||||
entryPoints: [options.filepath],
|
||||
absWorkingDir: cwd,
|
||||
outfile: "out.js",
|
||||
format,
|
||||
platform: "node",
|
||||
sourcemap: "inline",
|
||||
bundle: true,
|
||||
metafile: true,
|
||||
write: false,
|
||||
...(tsconfig == null ? void 0 : tsconfig.path) ? { tsconfig: tsconfig.path } : { tsconfigRaw: (tsconfig == null ? void 0 : tsconfig.data) || {} },
|
||||
plugins: [
|
||||
...((_d = options.esbuildOptions) == null ? void 0 : _d.plugins) || [],
|
||||
externalPlugin({
|
||||
external: options.external,
|
||||
notExternal: [...options.notExternal || [], ...resolvePaths],
|
||||
externalNodeModules: (_e = options.externalNodeModules) != null ? _e : !options.filepath.match(PATH_NODE_MODULES_RE)
|
||||
}),
|
||||
injectFileScopePlugin({
|
||||
readFile: options.readFile
|
||||
})
|
||||
]
|
||||
};
|
||||
const run = async () => {
|
||||
if (!(watchMode || options.onRebuild)) {
|
||||
const result = await build(esbuildOptions);
|
||||
resolve(await extractResult(result));
|
||||
} else {
|
||||
const rebuildCallback = typeof watchMode === "object" && typeof watchMode.onRebuild === "function" ? watchMode.onRebuild : async (error, result) => {
|
||||
var _a2, _b2;
|
||||
if (error) {
|
||||
(_a2 = options.onRebuild) == null ? void 0 : _a2.call(options, { err: error });
|
||||
}
|
||||
if (result) {
|
||||
(_b2 = options.onRebuild) == null ? void 0 : _b2.call(options, await extractResult(result));
|
||||
}
|
||||
};
|
||||
const onRebuildPlugin = () => {
|
||||
return {
|
||||
name: "bundle-require:on-rebuild",
|
||||
setup(ctx2) {
|
||||
let count = 0;
|
||||
ctx2.onEnd(async (result) => {
|
||||
if (count++ === 0) {
|
||||
if (result.errors.length === 0)
|
||||
resolve(await extractResult(result));
|
||||
} else {
|
||||
if (result.errors.length > 0) {
|
||||
return rebuildCallback(
|
||||
{ errors: result.errors, warnings: result.warnings },
|
||||
null
|
||||
);
|
||||
}
|
||||
if (result) {
|
||||
rebuildCallback(null, result);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
||||
esbuildOptions.plugins.push(onRebuildPlugin());
|
||||
const ctx = await context(esbuildOptions);
|
||||
await ctx.watch();
|
||||
}
|
||||
};
|
||||
run().catch(reject);
|
||||
});
|
||||
}
|
||||
export {
|
||||
JS_EXT_RE,
|
||||
bundleRequire,
|
||||
dynamicImport,
|
||||
externalPlugin,
|
||||
injectFileScopePlugin,
|
||||
loadTsConfig,
|
||||
match,
|
||||
tsconfigPathsToRegExp
|
||||
};
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"name": "bundle-require",
|
||||
"version": "5.1.0",
|
||||
"description": "bundle and require a file",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"exports": {
|
||||
".": {
|
||||
"import": "./dist/index.js",
|
||||
"default": "./dist/index.cjs"
|
||||
}
|
||||
},
|
||||
"types": "./dist/index.d.ts",
|
||||
"scripts": {
|
||||
"build": "tsup src/index.ts --format esm,cjs --dts-resolve --target node12.20.0",
|
||||
"test": "npm run build && vitest run",
|
||||
"prepublishOnly": "npm run build"
|
||||
},
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@egoist/prettier-config": "1.0.0",
|
||||
"@types/node": "18.11.18",
|
||||
"esbuild": "0.18.20",
|
||||
"prettier": "2.8.3",
|
||||
"tsup": "6.5.0",
|
||||
"typescript": "4.9.5",
|
||||
"vitest": "0.28.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"load-tsconfig": "^0.2.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"esbuild": ">=0.18"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user