-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Unify code-base as ts and transpile to cjs for publish
- Loading branch information
Showing
126 changed files
with
14,798 additions
and
9,088 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
'use strict' | ||
|
||
const { isEsmId } = require('../scripts/packages') | ||
|
||
module.exports = { | ||
plugins: [ | ||
'@babel/plugin-proposal-export-default-from', | ||
'@babel/plugin-transform-export-namespace-from', | ||
[ | ||
'@babel/plugin-transform-runtime', | ||
{ | ||
absoluteRuntime: false, | ||
corejs: false, | ||
helpers: true, | ||
regenerator: false, | ||
version: '^7.24.6' | ||
} | ||
], | ||
[ | ||
'@babel/plugin-transform-modules-commonjs', | ||
{ | ||
allowTopLevelThis: true, | ||
importInterop: (specifier, requestingFilename) => { | ||
if (requestingFilename) { | ||
const specIsEsm = isEsmId(specifier, requestingFilename) | ||
const parentIsEsm = isEsmId(requestingFilename) | ||
if (specIsEsm && parentIsEsm) { | ||
return 'none' | ||
} | ||
if (specIsEsm) { | ||
return 'babel' | ||
} | ||
} | ||
return 'node' | ||
} | ||
} | ||
] | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,229 @@ | ||
import { builtinModules, createRequire } from 'node:module' | ||
import path from 'node:path' | ||
import { fileURLToPath } from 'node:url' | ||
|
||
import commonjs from '@rollup/plugin-commonjs' | ||
import replace from '@rollup/plugin-replace' | ||
import { nodeResolve } from '@rollup/plugin-node-resolve' | ||
import rangesIntersect from 'semver/ranges/intersects.js' | ||
import { readPackageUpSync } from 'read-package-up' | ||
|
||
import { loadJSON } from '../scripts/files.js' | ||
import { | ||
getPackageName, | ||
getPackageNameEnd, | ||
isEsmId, | ||
normalizeId, | ||
isPackageName, | ||
isBuiltin, | ||
resolveId | ||
} from '../scripts/packages.js' | ||
import { escapeRegExp } from '../scripts/strings.js' | ||
import socketModifyPlugin from '../scripts/rollup/socket-modify-plugin.js' | ||
|
||
const __dirname = fileURLToPath(new URL('.', import.meta.url)) | ||
const require = createRequire(import.meta.url) | ||
|
||
const ts = require('rollup-plugin-ts') | ||
|
||
const ENTRY_SUFFIX = '?commonjs-entry' | ||
const EXTERNAL_SUFFIX = '?commonjs-external' | ||
|
||
const builtinAliases = builtinModules.reduce((o, n) => { | ||
o[n] = `node:${n}` | ||
return o | ||
}, {}) | ||
|
||
const rootPath = path.resolve(__dirname, '..') | ||
const babelConfigPath = path.join(__dirname, 'babel.config.js') | ||
const tsconfigPath = path.join(__dirname, 'tsconfig.rollup.json') | ||
|
||
const babelConfig = require(babelConfigPath) | ||
const { dependencies: pkgDeps, devDependencies: pkgDevDeps } = loadJSON( | ||
path.resolve(rootPath, 'package.json') | ||
) | ||
|
||
const customResolver = nodeResolve({ | ||
exportConditions: ['node'], | ||
preferBuiltins: true | ||
}) | ||
|
||
export default (extendConfig = {}) => { | ||
const depStats = { | ||
dependencies: { __proto__: null }, | ||
devDependencies: { __proto__: null }, | ||
esm: { __proto__: null }, | ||
external: { __proto__: null }, | ||
transitives: { __proto__: null } | ||
} | ||
|
||
const config = { | ||
__proto__: { | ||
meta: { | ||
depStats | ||
} | ||
}, | ||
external(id_, parentId_) { | ||
if (id_.endsWith(EXTERNAL_SUFFIX) || isBuiltin(id_)) { | ||
return true | ||
} | ||
const id = normalizeId(id_) | ||
if (id.endsWith('.cjs') || id.endsWith('.json')) { | ||
return true | ||
} | ||
if ( | ||
id.endsWith('.mjs') || | ||
id.endsWith('.mts') || | ||
id.endsWith('.ts') || | ||
!isPackageName(id) | ||
) { | ||
return false | ||
} | ||
const name = getPackageName(id) | ||
const parentId = parentId_ ? resolveId(parentId_) : undefined | ||
const resolvedId = resolveId(id, parentId) | ||
if (isEsmId(resolvedId, parentId)) { | ||
const parentPkg = parentId | ||
? readPackageUpSync({ cwd: path.dirname(parentId) })?.packageJson | ||
: undefined | ||
depStats.esm[name] = | ||
pkgDeps[name] ?? | ||
pkgDevDeps[name] ?? | ||
parentPkg?.dependencies?.[name] ?? | ||
parentPkg?.optionalDependencies?.[name] ?? | ||
parentPkg?.peerDependencies?.[name] ?? | ||
readPackageUpSync({ cwd: path.dirname(resolvedId) })?.packageJson | ||
?.version ?? | ||
'' | ||
return false | ||
} | ||
const parentNodeModulesIndex = parentId.lastIndexOf('/node_modules/') | ||
if (parentNodeModulesIndex !== -1) { | ||
const parentNameStart = parentNodeModulesIndex + 14 | ||
const parentNameEnd = getPackageNameEnd(parentId, parentNameStart) | ||
const { | ||
version, | ||
dependencies = {}, | ||
optionalDependencies = {}, | ||
peerDependencies = {} | ||
} = loadJSON(`${parentId.slice(0, parentNameEnd)}/package.json`) | ||
const curRange = | ||
dependencies[name] ?? | ||
optionalDependencies[name] ?? | ||
peerDependencies[name] ?? | ||
version | ||
const seenRange = pkgDeps[name] ?? depStats.external[name] | ||
if (seenRange) { | ||
return rangesIntersect(seenRange, curRange) | ||
} | ||
depStats.external[name] = curRange | ||
depStats.transitives[name] = curRange | ||
} else if (pkgDeps[name]) { | ||
depStats.external[name] = pkgDeps[name] | ||
depStats.dependencies[name] = pkgDeps[name] | ||
} else if (pkgDevDeps[name]) { | ||
depStats.devDependencies[name] = pkgDevDeps[name] | ||
} | ||
return true | ||
}, | ||
...extendConfig, | ||
plugins: [ | ||
customResolver, | ||
ts({ | ||
transpiler: 'babel', | ||
browserslist: false, | ||
transpileOnly: true, | ||
exclude: ['**/*.json'], | ||
babelConfig, | ||
tsconfig: tsconfigPath | ||
}), | ||
// Convert un-prefixed built-in imports into "node:"" prefixed forms. | ||
replace({ | ||
delimiters: ['(?<=(?:require\\(|from\\s*)["\'])', '(?=["\'])'], | ||
preventAssignment: false, | ||
values: builtinAliases | ||
}), | ||
// Convert `require('u' + 'rl')` into something like `require$$2$3`. | ||
socketModifyPlugin({ | ||
find: /require\('u' \+ 'rl'\)/g, | ||
replace(match) { | ||
return ( | ||
/(?<=var +)[$\w]+(?= *= *require\('node:url'\))/.exec( | ||
this.input | ||
)?.[0] ?? match | ||
) | ||
} | ||
}), | ||
// Remove bare require calls, e.g. require calls not associated with an | ||
// import binding: | ||
// require('node:util') | ||
// require('graceful-fs') | ||
socketModifyPlugin({ | ||
find: /^\s*require\(["'].+?["']\);?\r?\n/gm, | ||
replace: '' | ||
}), | ||
// Fix incorrectly set "spinners" binding caused by a transpilation bug | ||
// https://github.com/sindresorhus/ora/blob/main/index.js#L416C2-L416C50 | ||
// export {default as spinners} from 'cli-spinners' | ||
socketModifyPlugin({ | ||
find: /(?<=ora[^.]+\.spinners\s*=\s*)[$\w]+/g, | ||
replace(match) { | ||
return ( | ||
new RegExp(`(?<=${escapeRegExp(match)}\\s*=\\s*)[$\\w]+`).exec( | ||
this.input | ||
)?.[0] ?? match | ||
) | ||
} | ||
}), | ||
commonjs({ | ||
ignoreDynamicRequires: true, | ||
ignoreGlobal: true, | ||
ignoreTryCatch: true, | ||
defaultIsModuleExports: true, | ||
transformMixedEsModules: true, | ||
extensions: ['.cjs', '.js', '.ts', `.ts${ENTRY_SUFFIX}`] | ||
}), | ||
...(extendConfig.plugins ?? []) | ||
] | ||
} | ||
|
||
const output = ( | ||
Array.isArray(config.output) | ||
? config.output | ||
: config.output | ||
? [config.output] | ||
: [] | ||
).map(o => ({ | ||
...o, | ||
chunkFileNames: '[name].js', | ||
manualChunks(id) { | ||
if (id.includes('/node_modules/')) { | ||
return 'vendor' | ||
} | ||
} | ||
})) | ||
|
||
// Replace hard-coded absolute paths in source with hard-coded relative paths. | ||
const replacePlugin = replace({ | ||
delimiters: ['(?<=["\'])', '/'], | ||
preventAssignment: false, | ||
values: { | ||
[rootPath]: '../' | ||
} | ||
}) | ||
|
||
const replaceOutputPlugin = { | ||
name: replacePlugin.name, | ||
renderChunk: replacePlugin.renderChunk | ||
} | ||
|
||
for (const o of output) { | ||
o.plugins = [ | ||
...(Array.isArray(o.plugins) ? o.plugins : []), | ||
replaceOutputPlugin | ||
] | ||
} | ||
|
||
config.output = output | ||
return config | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
import { chmodSync, readFileSync, writeFileSync } from 'node:fs' | ||
import path from 'node:path' | ||
import { fileURLToPath } from 'node:url' | ||
|
||
import { loadJSON } from '../scripts/files.js' | ||
import { hasKeys } from '../scripts/objects.js' | ||
import { toSortedObject } from '../scripts/sorts.js' | ||
import { formatObject } from '../scripts/strings.js' | ||
|
||
import baseConfig from './rollup.base.config.mjs' | ||
|
||
const __dirname = fileURLToPath(new URL('.', import.meta.url)) | ||
|
||
const rootPath = path.resolve(__dirname, '..') | ||
const depStatsPath = path.join(rootPath, '.dep-stats.json') | ||
const distPath = path.join(rootPath, 'dist') | ||
const srcPath = path.join(rootPath, 'src') | ||
|
||
const pkgJSONPath = path.resolve(rootPath, 'package.json') | ||
const pkgJSON = loadJSON(pkgJSONPath) | ||
|
||
export default () => { | ||
const config = baseConfig({ | ||
input: { | ||
cli: `${srcPath}/cli.ts`, | ||
'npm-cli': `${srcPath}/shadow/npm-cli.ts`, | ||
'npx-cli': `${srcPath}/shadow/npx-cli.ts`, | ||
'npm-injection': `${srcPath}/shadow/npm-injection.ts` | ||
}, | ||
output: [ | ||
{ | ||
dir: 'dist', | ||
entryFileNames: '[name].js', | ||
format: 'cjs', | ||
exports: 'auto', | ||
externalLiveBindings: false, | ||
freeze: false | ||
} | ||
], | ||
plugins: [ | ||
{ | ||
writeBundle() { | ||
const { '@cyclonedx/cdxgen': cdxgenRange, synp: synpRange } = | ||
pkgJSON.dependencies | ||
const { depStats } = config.meta | ||
|
||
// Manually add @cyclonedx/cdxgen and synp as they are not directly | ||
// referenced in the code but used through spawned processes. | ||
depStats.dependencies['@cyclonedx/cdxgen'] = cdxgenRange | ||
depStats.dependencies.synp = synpRange | ||
depStats.external['@cyclonedx/cdxgen'] = cdxgenRange | ||
depStats.external.synp = synpRange | ||
|
||
try { | ||
// Remove transitives from dependencies | ||
const oldDepStats = loadJSON(depStatsPath) | ||
for (const key of Object.keys(oldDepStats.transitives)) { | ||
if (pkgJSON.dependencies[key]) { | ||
depStats.transitives[key] = pkgJSON.dependencies[key] | ||
depStats.external[key] = pkgJSON.dependencies[key] | ||
delete depStats.dependencies[key] | ||
} | ||
} | ||
} catch {} | ||
|
||
depStats.dependencies = toSortedObject(depStats.dependencies) | ||
depStats.devDependencies = toSortedObject(depStats.devDependencies) | ||
depStats.esm = toSortedObject(depStats.esm) | ||
depStats.external = toSortedObject(depStats.external) | ||
depStats.transitives = toSortedObject(depStats.transitives) | ||
|
||
// Write dep stats | ||
writeFileSync(depStatsPath, `${formatObject(depStats)}\n`, 'utf8') | ||
|
||
// Make dist files chmod +x | ||
chmodSync(path.join(distPath, 'cli.js'), 0o755) | ||
chmodSync(path.join(distPath, 'npm-cli.js'), 0o755) | ||
chmodSync(path.join(distPath, 'npx-cli.js'), 0o755) | ||
|
||
// Update dependencies with additional inlined modules | ||
writeFileSync( | ||
pkgJSONPath, | ||
readFileSync(pkgJSONPath, 'utf8').replace( | ||
/(?<="dependencies":\s*)\{[^\}]*\}/, | ||
() => { | ||
const deps = { | ||
...depStats.dependencies, | ||
...depStats.transitives | ||
} | ||
const formatted = formatObject(deps, 4) | ||
return hasKeys(deps) ? formatted.replace('}', ' }') : formatted | ||
} | ||
), | ||
'utf8' | ||
) | ||
} | ||
} | ||
] | ||
}) | ||
|
||
return config | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import path from 'node:path' | ||
import { fileURLToPath } from 'node:url' | ||
|
||
import baseConfig from './rollup.base.config.mjs' | ||
|
||
const __dirname = fileURLToPath(new URL('.', import.meta.url)) | ||
|
||
const rootPath = path.resolve(__dirname, '..') | ||
const srcPath = path.join(rootPath, 'src') | ||
|
||
export default () => | ||
baseConfig({ | ||
input: { | ||
'path-resolve': `${srcPath}/utils/path-resolve.ts` | ||
}, | ||
output: [ | ||
{ | ||
dir: 'test/dist', | ||
entryFileNames: '[name].js', | ||
format: 'cjs', | ||
exports: 'auto', | ||
externalLiveBindings: false, | ||
freeze: false | ||
} | ||
] | ||
}) |
Oops, something went wrong.