UNPKG

siroc

Version:

Zero-config build tooling for Node

1,216 lines (1,201 loc) 36.7 kB
#!/usr/bin/env node 'use strict' Object.defineProperty(exports, '__esModule', { value: true }) const upath = require('upath') const chalk = require('chalk') const fsExtra = require('fs-extra') const mkdist = require('mkdist') const rollup = require('rollup') const consola = require('consola') const _glob = require('glob') const _jiti = require('jiti') const aliasPlugin = require('@rollup/plugin-alias') const commonjsPlugin = require('@rollup/plugin-commonjs') const jsonPlugin = require('@rollup/plugin-json') const replacePlugin = require('@rollup/plugin-replace') const nodeResolvePlugin = require('@rollup/plugin-node-resolve') const defu = require('defu') const dts = require('rollup-plugin-dts') const esbuild = require('rollup-plugin-esbuild') const detectIndent = require('detect-indent') const execa = require('execa') const sortPackageJson = require('sort-package-json') const Module = require('module') function _interopDefaultLegacy(e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e } } const chalk__default = /*#__PURE__*/ _interopDefaultLegacy(chalk) const consola__default = /*#__PURE__*/ _interopDefaultLegacy(consola) const _glob__default = /*#__PURE__*/ _interopDefaultLegacy(_glob) const _jiti__default = /*#__PURE__*/ _interopDefaultLegacy(_jiti) const aliasPlugin__default = /*#__PURE__*/ _interopDefaultLegacy(aliasPlugin) const commonjsPlugin__default = /*#__PURE__*/ _interopDefaultLegacy(commonjsPlugin) const jsonPlugin__default = /*#__PURE__*/ _interopDefaultLegacy(jsonPlugin) const replacePlugin__default = /*#__PURE__*/ _interopDefaultLegacy(replacePlugin) const nodeResolvePlugin__default = /*#__PURE__*/ _interopDefaultLegacy(nodeResolvePlugin) const defu__default = /*#__PURE__*/ _interopDefaultLegacy(defu) const dts__default = /*#__PURE__*/ _interopDefaultLegacy(dts) const esbuild__default = /*#__PURE__*/ _interopDefaultLegacy(esbuild) const detectIndent__default = /*#__PURE__*/ _interopDefaultLegacy(detectIndent) const execa__default = /*#__PURE__*/ _interopDefaultLegacy(execa) const sortPackageJson__default = /*#__PURE__*/ _interopDefaultLegacy(sortPackageJson) const Module__default = /*#__PURE__*/ _interopDefaultLegacy(Module) function loadAllSettled() { Promise.allSettled = function (values) { return Promise.all( Array.from(values).map(promise => { if (promise instanceof Promise) { return promise .then(value => ({ status: 'fulfilled', value, })) .catch(reason => ({ status: 'rejected', reason, })) } return { status: 'fulfilled', value: promise, } }) ) } } function loadFromEntries() { Object.fromEntries = function (entries) { const newObject = {} for (const [key, value] of entries) { if (typeof key === 'string') newObject[key] = value } return newObject } } var __async$2 = (__this, __arguments, generator) => { return new Promise((resolve, reject) => { var fulfilled = value => { try { step(generator.next(value)) } catch (e) { reject(e) } } var rejected = value => { try { step(generator.throw(value)) } catch (e) { reject(e) } } var step = x => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected) step((generator = generator.apply(__this, __arguments)).next()) }) } const jiti = _jiti__default['default']() if (!Object.fromEntries) loadFromEntries() if (!Promise.allSettled) loadAllSettled() const glob = pattern => new Promise((resolve, reject) => _glob__default['default'](pattern, (err, matches) => { if (err) return reject(err) resolve(matches) }) ) const sortObjectKeys = obj => Object.fromEntries( Object.entries(obj).sort(([key1], [key2]) => +key2 - +key1) ) const tryJSON = id => { try { return fsExtra.readJSONSync(id) } catch (e) { return void 0 } } const tryRequire = id => { try { if (upath.extname(id) === 'json') return tryJSON(id) const contents = jiti(id) if ('default' in contents) return contents.default return contents } catch (e) { return void 0 } } const ensureUnique = items => Array.from(new Set(items)) const groupBy = (collection, key) => { const groups = {} collection.forEach(entry => { groups[entry[key]] = groups[entry[key]] || [] groups[entry[key]].push(entry) }) return groups } const includeDefinedProperties = options => Object.fromEntries( Object.entries(options).filter(([_, value]) => value !== void 0) ) const includeIf = (test, itemFactory) => (test ? [itemFactory(test)] : []) const runInParallel = (items, cb) => __async$2(undefined, null, function* () { if (Array.isArray(items)) return Promise.allSettled( items.map((item, index2) => __async$2(this, null, function* () { return cb(item, index2) }) ) ).then(results => results.map(result => { if (result.status === 'rejected') consola__default['default'].error(result.reason) return result }) ) const promises = [] let index = 0 for (const item of items) { try { promises.push(Promise.resolve(cb(item, index))) } catch (e) { promises.push(Promise.reject(e)) } index++ } return Promise.allSettled(promises).then(results => results.map(result => { if (result.status === 'rejected') consola__default['default'].error(result.reason) return result }) ) }) const asArray = item => item !== void 0 ? (Array.isArray(item) ? item : [item]) : [] const walkDownDirectory = pathname => pathname.split(upath.sep).slice(1).join(upath.sep) const getEntrypointPaths = path => { if (path.startsWith('./')) path = path.slice(2) const filenames = new Set() let cwd = path do { filenames.add(cwd) cwd = walkDownDirectory(cwd) } while (cwd) return Array.from(filenames) } const getEntrypointFilenames = path => { if (path.startsWith('./')) path = path.slice(2) const filenames = new Set() let cwd = path do { const basefile = cwd.split('.').slice(0, -1).join('.') const withoutType = basefile.split('.').slice(0, 1).join('') ;[ basefile, `${basefile}/index`, withoutType, `${withoutType}/index`, ].forEach(name => filenames.add(name)) cwd = walkDownDirectory(cwd) } while (cwd) filenames.add('index') return Array.from(filenames) .map(name => [`${name}.ts`, `${name}.js`]) .reduce((names, arr) => { arr.forEach(name => names.push(name)) return names }, []) } const getFlatValues = obj => { return Object.values(obj) .map(ex => (typeof ex === 'string' ? ex : Object.values(ex))) .reduce((flatArray, item) => { if (Array.isArray(item)) return [...flatArray, ...item] flatArray.push(item) return flatArray }, []) } var __defProp$2 = Object.defineProperty var __defProps$1 = Object.defineProperties var __getOwnPropDescs$1 = Object.getOwnPropertyDescriptors var __getOwnPropSymbols$2 = Object.getOwnPropertySymbols var __hasOwnProp$2 = Object.prototype.hasOwnProperty var __propIsEnum$2 = Object.prototype.propertyIsEnumerable var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value, }) : (obj[key] = value) var __spreadValues$2 = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp$2.call(b, prop)) __defNormalProp$2(a, prop, b[prop]) if (__getOwnPropSymbols$2) for (var prop of __getOwnPropSymbols$2(b)) { if (__propIsEnum$2.call(b, prop)) __defNormalProp$2(a, prop, b[prop]) } return a } var __spreadProps$1 = (a, b) => __defProps$1(a, __getOwnPropDescs$1(b)) var __async$1 = (__this, __arguments, generator) => { return new Promise((resolve2, reject) => { var fulfilled = value => { try { step(generator.next(value)) } catch (e) { reject(e) } } var rejected = value => { try { step(generator.throw(value)) } catch (e) { reject(e) } } var step = x => x.done ? resolve2(x.value) : Promise.resolve(x.value).then(fulfilled, rejected) step((generator = generator.apply(__this, __arguments)).next()) }) } const defineSirocConfig = options => options const configPaths = [ 'siroc.config.ts', 'siroc.config.js', 'siroc.config.json', 'package.js', ] const DEFAULTS = { rootDir: process.cwd(), build: true, suffix: process.env.PACKAGE_SUFFIX ? `-${process.env.PACKAGE_SUFFIX}` : '', hooks: {}, commands: {}, mkdist: {}, } class Package { constructor(options = {}) { this.options = Object.assign({}, DEFAULTS, options) this.logger = consola__default['default'] const blob = this.loadPackageJSON(false) this.pkg = JSON.parse(blob) this.options.pkgIndent = this.options.pkgIndent || detectIndent__default['default'](blob).indent this.logger = consola__default['default'].withTag(this.pkg.name) this.loadConfig() } loadPackageJSON(parse = true) { try { const blob = fsExtra.readFileSync( this.resolvePath('package.json'), 'utf8' ) if (parse) return JSON.parse(blob) return blob } catch (e) { if (this.options.rootDir === '/') { this.logger.error( `Could not locate a ${chalk.bold('package.json')} in ${chalk.bold( DEFAULTS.rootDir )} or its parent directories.` ) throw new Error( `Could not locate a package.json in ${DEFAULTS.rootDir} or its parent directories.` ) } this.options.rootDir = this.resolvePath('..') return this.loadPackageJSON() } } resolvePath(...pathSegments) { return upath.resolve(this.options.rootDir, ...pathSegments) } loadConfig() { configPaths.some(path => { const configPath = this.resolvePath(path) const config = tryRequire(configPath) if (!config) return false Object.assign(this.options, config) return true }) } callHook(name, options) { return __async$1(this, null, function* () { const fns = this.options.hooks[name] if (!fns) return const fnArray = Array.isArray(fns) ? fns : [fns] try { yield runInParallel(fnArray, fn => __async$1(this, null, function* () { return fn(this, options) }) ) } catch (e) { this.logger.error(`Couldn't run hook for ${this.pkg.name}.`) } }) } load(relativePath, opts) { return new Package( Object.assign( { rootDir: this.resolvePath(relativePath), }, opts ) ) } writePackage() { return __async$1(this, null, function* () { const pkgPath = this.resolvePath('package.json') this.logger.debug('Writing', pkgPath) yield fsExtra.writeFile( pkgPath, JSON.stringify(this.pkg, null, this.options.pkgIndent) + '\n' ) }) } get version() { const date = Math.round(Date.now() / (1e3 * 60)) const gitCommit = this.shortCommit const baseVersion = this.pkg.version.split('-')[0] return `${baseVersion}-${date}.${gitCommit}` } suffixAndVersion() { this.logger.info(`Adding suffix ${this.options.suffix}`) const oldPkgName = this.pkg.name if (!oldPkgName.includes(this.options.suffix)) { this.pkg.name += this.options.suffix } if (this.pkg.dependencies) { for (const oldName of this.options.linkedDependencies || []) { const name = oldName + this.options.suffix const version = this.pkg.dependencies[oldName] || this.pkg.dependencies[name] delete this.pkg.dependencies[oldName] this.pkg.dependencies[name] = version } } if (typeof this.pkg.bin === 'string') { const { bin } = this.pkg this.pkg.bin = { [oldPkgName]: bin, [this.pkg.name]: bin, } } this.pkg.version = this.version } syncLinkedDependencies() { for (const _name of this.options.linkedDependencies || []) { const name = _name + (this.options.suffix || '') const pkg = tryJSON(`${name}/package.json`) || tryJSON(`${_name}/package.json`) if ( !pkg || !pkg.version || !this.pkg.dependencies || !this.pkg.dependencies[name] ) { continue } const currentVersion = this.pkg.dependencies[name] const caret = currentVersion[0] === '^' this.pkg.dependencies[name] = caret ? `^${pkg.version}` : pkg.version } } publish(tag = 'latest') { this.logger.info( `publishing ${this.pkg.name}@${this.pkg.version} with tag ${tag}` ) this.exec(`npm publish --tag ${tag}`) } copyFieldsFrom(source, fields = []) { for (const field of fields) { this.pkg[field] = source.pkg[field] } } setBinaryPermissions() { return __async$1(this, null, function* () { yield Promise.all( this.binaries.map(([binary]) => fsExtra.chmod(binary, 511)) ) }) } createBinaryStubs() { return __async$1(this, null, function* () { yield runInParallel(this.binaries, _0 => __async$1(this, [_0], function* ([binary, entrypoint]) { if (!entrypoint) return const outDir = upath.dirname(binary) if (!fsExtra.existsSync(outDir)) yield fsExtra.mkdirp(outDir) const absPath = entrypoint.replace(/(\.[jt]s)$/, '') yield fsExtra.writeFile( binary, [ `#!/usr/bin/env node`, `const jiti = require('jiti')()`, `module.exports = jiti('${absPath}')`, ].join('\n') ) yield this.setBinaryPermissions() }) ) }) } createStub(path, cjs = false) { return __async$1(this, null, function* () { if (!path || !this.entrypoint || !this.options.build) return const outFile = this.resolvePath(path) const outDir = upath.dirname(outFile) if (!fsExtra.existsSync(outDir)) yield fsExtra.mkdirp(outDir) const relativeEntrypoint = upath .relative(outDir, this.entrypoint) .replace(/(\.[cm]?[jt]s)$/, '') const stub = cjs ? [ `const jiti = require('jiti')()`, `module.exports = jiti('./${relativeEntrypoint}')`, ].join('\n') : `export * from './${relativeEntrypoint}'` yield fsExtra.writeFile(outFile, stub) }) } createStubs() { return __async$1(this, null, function* () { return Promise.all([ this.createBinaryStubs(), this.createStub(this.pkg.main, true), this.createStub(this.pkg.module), this.createStub(this.pkg.types), ]) }) } copyFilesFrom(source, files) { return __async$1(this, null, function* () { for (const file of files || source.pkg.files || []) { const src = upath.resolve(source.options.rootDir, file) const dst = upath.resolve(this.options.rootDir, file) yield fsExtra.copy(src, dst) } }) } autoFix() { this.pkg = sortPackageJson__default['default'](this.pkg) if (this.options.sortDependencies) this.sortDependencies() } sortDependencies() { if (this.pkg.dependencies) { this.pkg.dependencies = sortObjectKeys(this.pkg.dependencies) } if (this.pkg.devDependencies) { this.pkg.devDependencies = sortObjectKeys(this.pkg.devDependencies) } } execInteractive(command) { const options = { cwd: this.options.rootDir, env: process.env, shell: true, stdio: 'inherit', } return execa__default['default'].command(command, options) } get exports() { const { exports } = this.pkg const filterExports = item => ![ this.pkg.main, this.pkg.module, this.pkg.browser, `./${this.pkg.main}`, `./${this.pkg.module}`, `./${this.pkg.browser}`, ].includes(item) && !item.endsWith('/') && !item.includes('*') if (!exports) return [] if (typeof exports === 'string') return [exports].filter(filterExports) if (Array.isArray(exports)) return exports.filter(filterExports) return getFlatValues(exports).filter(filterExports) } get folderExports() { const { exports } = this.pkg const filterExports = item => /[a-z]\/\*(\.[a-z]*)?$/.test(item) if (!exports) return [] if (typeof exports === 'string') return [exports].filter(filterExports) if (Array.isArray(exports)) return exports.filter(filterExports) return getFlatValues(exports).filter(filterExports) } exec(command, { silent = false } = {}) { const options = { cwd: this.options.rootDir, env: process.env, } const r = execa__default['default'].commandSync(command, options) if (!silent) { if (r.failed) { this.logger.error(command, r.stderr.trim()) } else { this.logger.success(command, r.stdout.trim()) } } return { signal: r.signal, stdout: String(r.stdout).trim(), stderr: String(r.stderr).trim(), } } resolveEntrypoint(path = this.pkg.main) { if (!path) return void 0 let input const filenames = getEntrypointFilenames(path) filenames.some(filename => { input = this.resolvePath('src', filename) return fsExtra.existsSync(input) }) return input } resolveEntrypointFolder(path = this.pkg.main) { if (!path) return void 0 let input const paths = getEntrypointPaths(path) paths.some(path2 => { input = this.resolvePath('src', path2) return fsExtra.pathExistsSync(input) }) return input } parsePerson(person) { const [_matchedName, name] = person.match(/(^[^<(]*[^ <(])/) || [] const [_matchedEmail, email] = person.match(/<(.*)>/) || [] const [_matchedUrl, url] = person.match(/\((.*)\)/) || [] return { name, email, url } } get contributors() { if (!this.pkg.contributors) return [] return this.pkg.contributors.map(person => { if (typeof person === 'string') return this.parsePerson(person) return person }) } get entrypoint() { return this.resolveEntrypoint() } get binaries() { const { bin } = this.pkg const files = !bin ? [] : typeof bin === 'string' ? [bin] : Object.values(bin) return Array.from( new Set( files.map(file => [ this.resolvePath(file), this.resolveEntrypoint(file), ]) ) ) } getWorkspacePackages(packageNames) { return __async$1(this, null, function* () { const dirs = new Set() yield runInParallel(this.pkg.workspaces || ['.'], workspace => __async$1(this, null, function* () { ;(yield glob(workspace)).forEach(dir => dirs.add(dir)) }) ) const packages = yield runInParallel(dirs, dir => { if (!fsExtra.existsSync(this.resolvePath(dir, 'package.json'))) { throw new Error('Not a package directory.') } const pkg = new Package( __spreadProps$1(__spreadValues$2({}, this.options), { rootDir: this.resolvePath(dir), }) ) if (packageNames && !packageNames.includes(pkg.pkg.name)) { throw new Error('Not a selected package.') } return pkg }) return packages .filter(pkg => pkg.status === 'fulfilled') .map(pkg => pkg.value) }) } get shortCommit() { const { stdout } = this.exec('git rev-parse --short HEAD', { silent: true, }) return stdout } get branch() { const { stdout } = this.exec('git rev-parse --abbrev-ref HEAD', { silent: true, }) return stdout } get lastGitTag() { const { stdout } = this.exec('git --no-pager tag -l --sort=taggerdate', { silent: true, }) const r = stdout.split('\n') return r[r.length - 1] } } const blacklist = ['sys'] const builtins = Module__default['default'].builtinModules .filter( x => !/^_|^(internal|v8|node-inspect)\/|\//.test(x) && !blacklist.includes(x) ) .sort() const getNameFunction = (rootDir, packageName) => (filename, defaultSuffix = '', defaultFormat) => { return { dir: filename ? upath.resolve(rootDir, upath.dirname(filename)) : upath.resolve(rootDir, 'dist'), entryFileNames: filename ? upath.basename(filename) : `${packageName}${defaultSuffix}.js`, chunkFileNames: filename ? `${upath.basename(filename)}-[name].js` : `${packageName}-[name]${defaultSuffix}.js`, format: formatForName( filename ? upath.basename(filename) : `${packageName}${defaultSuffix}.js`, defaultFormat ), } } const formats = [ 'amd', 'cjs', 'es', 'iife', 'system', 'umd', 'commonjs', 'esm', 'module', 'systemjs', ] const formatForName = (filename, defaultFormat = 'cjs') => { const parts = filename.split('.') if (parts.length > 2) { const format = parts[parts.length - 2] if (formats.includes(format)) return format } if (parts[parts.length - 1] === 'mjs') return 'module' return defaultFormat } const shouldMinify = filename => { return !!filename.match(/\.min\.\w+$/) } const convertToUMDName = name => { const unnamspacedName = name.split('/').pop() return (unnamspacedName || name) .replace(/-./g, r => r[1].toUpperCase()) .replace(/^./, r => r.toUpperCase()) } var __defProp$1 = Object.defineProperty var __defProps = Object.defineProperties var __getOwnPropDescs = Object.getOwnPropertyDescriptors var __getOwnPropSymbols$1 = Object.getOwnPropertySymbols var __hasOwnProp$1 = Object.prototype.hasOwnProperty var __propIsEnum$1 = Object.prototype.propertyIsEnumerable var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value, }) : (obj[key] = value) var __spreadValues$1 = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp$1.call(b, prop)) __defNormalProp$1(a, prop, b[prop]) if (__getOwnPropSymbols$1) for (var prop of __getOwnPropSymbols$1(b)) { if (__propIsEnum$1.call(b, prop)) __defNormalProp$1(a, prop, b[prop]) } return a } var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)) var __objRest = (source, exclude) => { var target = {} for (var prop in source) if (__hasOwnProp$1.call(source, prop) && exclude.indexOf(prop) < 0) target[prop] = source[prop] if (source != null && __getOwnPropSymbols$1) for (var prop of __getOwnPropSymbols$1(source)) { if (exclude.indexOf(prop) < 0 && __propIsEnum$1.call(source, prop)) target[prop] = source[prop] } return target } const __NODE_ENV__ = process.env.NODE_ENV function regexpForPackage(name) { name = name.replace(/[\\/]/g, '[\\\\/]') return new RegExp(`(^|node_modules[\\\\/])${name}([\\\\/]|$)`, 'i') } function regexpForPackages(packages) { return Object.keys(packages || {}).map(regexpForPackage) } function getRollupConfig(_a, pkg = new Package(), override) { var _b = _a, { input, replace = {}, alias = {}, externals = [], dev = false, resolve: resolveOptions = { resolveOnly: [/^((?!node_modules).)*$/], preferBuiltins: true, }, plugins = [], esbuildOptions, } = _b, options = __objRest(_b, [ 'input', 'replace', 'alias', 'externals', 'dev', 'resolve', 'plugins', 'esbuildOptions', ]) const { binaries, entrypoint, exports, pkg: pkgConfig, options: { rootDir, suffix }, } = pkg const resolvePath = (...path) => upath.resolve(rootDir, ...path) input = input ? resolvePath(input) : entrypoint if (!input && !binaries.length && !exports.length) return [] const name = upath.basename(pkgConfig.name.replace(suffix, '')) const getFilenames = getNameFunction(rootDir, name) const external = [ ...regexpForPackages(pkgConfig.dependencies), ...regexpForPackages(pkgConfig.optionalDependencies), ...regexpForPackages(pkgConfig.peerDependencies), ...builtins, ...externals, ] const getDeclarationPlugins = () => [ jsonPlugin__default['default'](), dts__default['default']({ compilerOptions: { allowJs: true, }, }), ] const getPlugins = filename => [ aliasPlugin__default['default']({ entries: alias, }), replacePlugin__default['default']({ exclude: 'node_modules/**', preventAssignment: true, delimiters: ['', ''], values: __spreadValues$1( __spreadValues$1({}, includeDefinedProperties({ __NODE_ENV__ })), replace ), }), nodeResolvePlugin__default['default'](resolveOptions), commonjsPlugin__default['default']({ include: /node_modules/ }), esbuild__default['default']( __spreadValues$1( { target: 'es2018', minify: shouldMinify(filename), }, esbuildOptions ) ), jsonPlugin__default['default'](), ...plugins, ] const defaultOutputs = [ __spreadProps(__spreadValues$1({}, getFilenames(pkgConfig.main)), { preferConst: true, exports: 'auto', }), ...includeIf(!dev && pkgConfig.module, pkgModule => __spreadProps( __spreadValues$1({}, getFilenames(pkgModule, '.es', 'es')), { exports: 'auto', } ) ), ...includeIf(!dev && pkgConfig.browser, pkgBrowser => __spreadProps( __spreadValues$1({}, getFilenames(pkgBrowser, '.umd', 'umd')), { name: convertToUMDName(pkgConfig.name), exports: 'auto', } ) ), ] if (override) { return [ { input: override.input, output: __spreadProps( __spreadValues$1( __spreadValues$1( {}, getFilenames(override.output, override.format) ), override.format === 'umd' ? { name: convertToUMDName(pkgConfig.name) } : {} ), { preferConst: true, exports: 'auto', format: override.format, } ), external, plugins: getPlugins(override.output), }, ] } const typeEntrypoint = (pkgConfig.types || pkgConfig.typings) && pkg.resolveEntrypoint(pkgConfig.types || pkgConfig.typings) return [ ...binaries.map(([binary, input2]) => defu__default['default']({}, options, { input: input2, output: __spreadProps( __spreadValues$1({}, getFilenames(binary, '', 'cjs')), { preferConst: true, exports: 'auto', banner: '#!/usr/bin/env node\n', } ), external, plugins: getPlugins(binary), }) ), ...(input ? defaultOutputs.map(output => defu__default['default']({}, options, { input, output, external, plugins: getPlugins(output.entryFileNames), }) ) : []), ...includeIf(typeEntrypoint, input2 => ({ input: input2, output: { file: resolvePath(pkgConfig.types || pkgConfig.typings), format: 'es', exports: 'auto', }, external, plugins: getDeclarationPlugins(), })), ...exports .filter(outfile => outfile && !outfile.match(/\.json$/)) .map(outfile => defu__default['default']({}, options, { input: pkg.resolveEntrypoint(outfile), output: __spreadProps(__spreadValues$1({}, getFilenames(outfile)), { preferConst: true, exports: 'auto', }), external, plugins: getPlugins(outfile), }) ), ...exports .filter( outfile => outfile && !outfile.match(/\.json$/) && pkg.resolveEntrypoint(outfile) !== typeEntrypoint ) .map(outfile => defu__default['default']({}, options, { input: pkg.resolveEntrypoint(outfile), output: { file: resolvePath(outfile.replace(/(\.es)?\.m?js$/, '.d.ts')), format: 'es', exports: 'auto', }, external, plugins: getDeclarationPlugins(), }) ), ] } function hl(str) { return chalk__default['default'].green(str) } function prettyPath(p, highlight = true) { p = upath.relative(process.cwd(), p) return highlight ? hl(p) : p } const logRollupConfig = (pkg, config) => { config.forEach(item => { const input = typeof item.input === 'string' ? prettyPath(item.input, false).padEnd(30) + ' \u2192 ' : item.input const output = Array.isArray(item.output) ? item.output : [item.output] output.forEach(out => { const outfile = (out == null ? void 0 : out.file) || ((out == null ? void 0 : out.dir) ? out.dir + '/' : '') + String(out == null ? void 0 : out.entryFileNames) || '' const format = outfile.endsWith('.d.ts') ? '(dts)' : (out == null ? void 0 : out.format) ? `(${out.format})` : '' pkg.logger.debug(input, prettyPath(outfile), format) }) }) } var __defProp = Object.defineProperty var __getOwnPropSymbols = Object.getOwnPropertySymbols var __hasOwnProp = Object.prototype.hasOwnProperty var __propIsEnum = Object.prototype.propertyIsEnumerable var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value, }) : (obj[key] = value) var __spreadValues = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp.call(b, prop)) __defNormalProp(a, prop, b[prop]) if (__getOwnPropSymbols) for (var prop of __getOwnPropSymbols(b)) { if (__propIsEnum.call(b, prop)) __defNormalProp(a, prop, b[prop]) } return a } var __async = (__this, __arguments, generator) => { return new Promise((resolve, reject) => { var fulfilled = value => { try { step(generator.next(value)) } catch (e) { reject(e) } } var rejected = value => { try { step(generator.throw(value)) } catch (e) { reject(e) } } var step = x => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected) step((generator = generator.apply(__this, __arguments)).next()) }) } function removeBuildFolders(pkg) { return __async(this, null, function* () { const directories = ensureUnique( [ ...pkg.binaries.map(([bin]) => bin), ...includeIf(pkg.pkg.main, main => main), ] .map(file => upath.dirname(file)) .filter(dir => !dir.includes('src') && !['.', './'].includes(dir)) ) yield runInParallel(directories, dir => fsExtra.remove(dir)) }) } const build = (_0, ..._1) => __async( undefined, [_0, ..._1], function* ( pkg, { watch: shouldWatch = false, dev = shouldWatch, override } = {} ) { const { options: { suffix, linkedDependencies, rootDir, rollup: rollupOptions }, } = pkg const config = __spreadValues( { alias: {}, replace: {}, dev, }, rollupOptions ) if (suffix) { for (const _name of linkedDependencies || []) { const name = _name + suffix config.replace[`'${_name}'`] = `'${name}'` config.alias[_name] = name } } yield pkg.callHook('build:extend', { config }) const rollupConfig = getRollupConfig(config, pkg, override) yield pkg.callHook('build:extendRollup', { rollupConfig, }) logRollupConfig(pkg, rollupConfig) yield runInParallel(pkg.folderExports, folder => { const { 1: distDir = folder, 3: ext } = folder.match(/^([^*]+[^*/])[*/]+(\.([a-z]+))?$/) || [] const sourceFolder = pkg.resolveEntrypointFolder(distDir) if (!sourceFolder) return const srcDir = upath.relative(pkg.options.rootDir, sourceFolder) pkg.logger.info( `Transpiling \`./${srcDir}\` to \`${distDir}\` with ${chalk.bold( 'mkdist' )}.` ) mkdist.mkdist( __spreadValues( { srcDir, distDir: distDir.slice(2), rootDir: pkg.options.rootDir, ext: ['mjs', 'ts', 'js'].includes(ext) ? ext : void 0, }, pkg.options.mkdist ) ) }) if (shouldWatch) { const watcher = rollup.watch(rollupConfig) watcher.on('event', event => { switch (event.code) { case 'START': return pkg.logger.debug(`Watching ${pkg.pkg.name} for changes`) case 'BUNDLE_START': return pkg.logger.debug(`Building ${pkg.pkg.name}`) case 'BUNDLE_END': return case 'END': return pkg.logger.success(`Built ${chalk.bold(pkg.pkg.name)}`) case 'ERROR': formatError(rootDir, event.error) return pkg.logger.error(event.error) default: const _event = event return pkg.logger.info(JSON.stringify(_event)) } }) } else { pkg.logger.debug(`Building ${pkg.pkg.name}`) yield runInParallel(rollupConfig, config2 => __async(this, null, function* () { try { const bundle = yield rollup.rollup(config2) yield runInParallel(asArray(config2.output), outputConfig => __async(this, null, function* () { if (!outputConfig) { pkg.logger.error('No build defined in generated config.') process.exit(1) } const { output } = yield bundle.write(outputConfig) const { fileName } = output[0] let size try { const filePath = outputConfig.dir ? upath.join(outputConfig.dir, fileName) : outputConfig.file || fileName const { size: bytes } = yield fsExtra.stat(filePath) if (bytes > 500) { size = chalk.green( ' ' + chalk.bold((bytes / 1024).toFixed(1).padStart(5)) + ' kB' ) } else { size = chalk.green( ' ' + chalk.bold(String(bytes).padStart(5)) + ' B' ) } } catch (e) {} pkg.logger.success( `Built ${chalk.bold(pkg.pkg.name.padEnd(15))} ${chalk.gray( fileName.padStart(15) )}${size}` ) }) ) yield pkg.callHook('build:done', { bundle }) } catch (err) { const formattedError = formatError(rootDir, err) throw pkg.logger.error(formattedError) } }) ) } } ) const formatError = (rootDir, error) => { let loc = rootDir if (error.loc) { const { file, column, line } = error.loc loc = `${file}:${line}:${column}` } error.message = `[${error.code}] ${error.message} at ${loc}` return error } exports.Package = Package exports.asArray = asArray exports.build = build exports.defineSirocConfig = defineSirocConfig exports.ensureUnique = ensureUnique exports.getRollupConfig = getRollupConfig exports.glob = glob exports.groupBy = groupBy exports.includeDefinedProperties = includeDefinedProperties exports.includeIf = includeIf exports.logRollupConfig = logRollupConfig exports.regexpForPackage = regexpForPackage exports.removeBuildFolders = removeBuildFolders exports.runInParallel = runInParallel exports.sortObjectKeys = sortObjectKeys exports.tryJSON = tryJSON exports.tryRequire = tryRequire