Skip to content

Commit c9d92dd

Browse files
committed
Unify code-base as ts and transpile to cjs for publish
1 parent fcaad4a commit c9d92dd

File tree

133 files changed

+16482
-10809
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

133 files changed

+16482
-10809
lines changed

.config/babel.config.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
'use strict'
2+
3+
const { isEsmId } = require('../scripts/packages')
4+
5+
module.exports = {
6+
plugins: [
7+
'@babel/plugin-proposal-export-default-from',
8+
'@babel/plugin-transform-export-namespace-from',
9+
[
10+
'@babel/plugin-transform-runtime',
11+
{
12+
absoluteRuntime: false,
13+
corejs: false,
14+
helpers: true,
15+
regenerator: false,
16+
version: '^7.24.6'
17+
}
18+
],
19+
[
20+
'@babel/plugin-transform-modules-commonjs',
21+
{
22+
allowTopLevelThis: true,
23+
importInterop: (specifier, requestingFilename) => {
24+
if (requestingFilename) {
25+
const specIsEsm = isEsmId(specifier, requestingFilename)
26+
const parentIsEsm = isEsmId(requestingFilename)
27+
if (specIsEsm && parentIsEsm) {
28+
return 'none'
29+
}
30+
if (specIsEsm) {
31+
return 'babel'
32+
}
33+
}
34+
return 'node'
35+
}
36+
}
37+
]
38+
]
39+
}

.config/rollup.base.config.mjs

Lines changed: 229 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,229 @@
1+
import { builtinModules, createRequire } from 'node:module'
2+
import path from 'node:path'
3+
import { fileURLToPath } from 'node:url'
4+
5+
import commonjs from '@rollup/plugin-commonjs'
6+
import replace from '@rollup/plugin-replace'
7+
import { nodeResolve } from '@rollup/plugin-node-resolve'
8+
import rangesIntersect from 'semver/ranges/intersects.js'
9+
import { readPackageUpSync } from 'read-package-up'
10+
11+
import { loadJSON } from '../scripts/files.js'
12+
import {
13+
getPackageName,
14+
getPackageNameEnd,
15+
isEsmId,
16+
normalizeId,
17+
isPackageName,
18+
isBuiltin,
19+
resolveId
20+
} from '../scripts/packages.js'
21+
import { escapeRegExp } from '../scripts/strings.js'
22+
import socketModifyPlugin from '../scripts/rollup/socket-modify-plugin.js'
23+
24+
const __dirname = fileURLToPath(new URL('.', import.meta.url))
25+
const require = createRequire(import.meta.url)
26+
27+
const ts = require('rollup-plugin-ts')
28+
29+
const ENTRY_SUFFIX = '?commonjs-entry'
30+
const EXTERNAL_SUFFIX = '?commonjs-external'
31+
32+
const builtinAliases = builtinModules.reduce((o, n) => {
33+
o[n] = `node:${n}`
34+
return o
35+
}, {})
36+
37+
const rootPath = path.resolve(__dirname, '..')
38+
const babelConfigPath = path.join(__dirname, 'babel.config.js')
39+
const tsconfigPath = path.join(__dirname, 'tsconfig.rollup.json')
40+
41+
const babelConfig = require(babelConfigPath)
42+
const { dependencies: pkgDeps, devDependencies: pkgDevDeps } = loadJSON(
43+
path.resolve(rootPath, 'package.json')
44+
)
45+
46+
const customResolver = nodeResolve({
47+
exportConditions: ['node'],
48+
preferBuiltins: true
49+
})
50+
51+
export default (extendConfig = {}) => {
52+
const depStats = {
53+
dependencies: { __proto__: null },
54+
devDependencies: { __proto__: null },
55+
esm: { __proto__: null },
56+
external: { __proto__: null },
57+
transitives: { __proto__: null }
58+
}
59+
60+
const config = {
61+
__proto__: {
62+
meta: {
63+
depStats
64+
}
65+
},
66+
external(id_, parentId_) {
67+
if (id_.endsWith(EXTERNAL_SUFFIX) || isBuiltin(id_)) {
68+
return true
69+
}
70+
const id = normalizeId(id_)
71+
if (id.endsWith('.cjs') || id.endsWith('.json')) {
72+
return true
73+
}
74+
if (
75+
id.endsWith('.mjs') ||
76+
id.endsWith('.mts') ||
77+
id.endsWith('.ts') ||
78+
!isPackageName(id)
79+
) {
80+
return false
81+
}
82+
const name = getPackageName(id)
83+
const parentId = parentId_ ? resolveId(parentId_) : undefined
84+
const resolvedId = resolveId(id, parentId)
85+
if (isEsmId(resolvedId, parentId)) {
86+
const parentPkg = parentId
87+
? readPackageUpSync({ cwd: path.dirname(parentId) })?.packageJson
88+
: undefined
89+
depStats.esm[name] =
90+
pkgDeps[name] ??
91+
pkgDevDeps[name] ??
92+
parentPkg?.dependencies?.[name] ??
93+
parentPkg?.optionalDependencies?.[name] ??
94+
parentPkg?.peerDependencies?.[name] ??
95+
readPackageUpSync({ cwd: path.dirname(resolvedId) })?.packageJson
96+
?.version ??
97+
''
98+
return false
99+
}
100+
const parentNodeModulesIndex = parentId.lastIndexOf('/node_modules/')
101+
if (parentNodeModulesIndex !== -1) {
102+
const parentNameStart = parentNodeModulesIndex + 14
103+
const parentNameEnd = getPackageNameEnd(parentId, parentNameStart)
104+
const {
105+
version,
106+
dependencies = {},
107+
optionalDependencies = {},
108+
peerDependencies = {}
109+
} = loadJSON(`${parentId.slice(0, parentNameEnd)}/package.json`)
110+
const curRange =
111+
dependencies[name] ??
112+
optionalDependencies[name] ??
113+
peerDependencies[name] ??
114+
version
115+
const seenRange = pkgDeps[name] ?? depStats.external[name]
116+
if (seenRange) {
117+
return rangesIntersect(seenRange, curRange)
118+
}
119+
depStats.external[name] = curRange
120+
depStats.transitives[name] = curRange
121+
} else if (pkgDeps[name]) {
122+
depStats.external[name] = pkgDeps[name]
123+
depStats.dependencies[name] = pkgDeps[name]
124+
} else if (pkgDevDeps[name]) {
125+
depStats.devDependencies[name] = pkgDevDeps[name]
126+
}
127+
return true
128+
},
129+
...extendConfig,
130+
plugins: [
131+
customResolver,
132+
ts({
133+
transpiler: 'babel',
134+
browserslist: false,
135+
transpileOnly: true,
136+
exclude: ['**/*.json'],
137+
babelConfig,
138+
tsconfig: tsconfigPath
139+
}),
140+
// Convert un-prefixed built-in imports into "node:"" prefixed forms.
141+
replace({
142+
delimiters: ['(?<=(?:require\\(|from\\s*)["\'])', '(?=["\'])'],
143+
preventAssignment: false,
144+
values: builtinAliases
145+
}),
146+
// Convert `require('u' + 'rl')` into something like `require$$2$3`.
147+
socketModifyPlugin({
148+
find: /require\('u' \+ 'rl'\)/g,
149+
replace(match) {
150+
return (
151+
/(?<=var +)[$\w]+(?= *= *require\('node:url'\))/.exec(
152+
this.input
153+
)?.[0] ?? match
154+
)
155+
}
156+
}),
157+
// Remove bare require calls, e.g. require calls not associated with an
158+
// import binding:
159+
// require('node:util')
160+
// require('graceful-fs')
161+
socketModifyPlugin({
162+
find: /^\s*require\(["'].+?["']\);?\r?\n/gm,
163+
replace: ''
164+
}),
165+
// Fix incorrectly set "spinners" binding caused by a transpilation bug
166+
// https://github.com/sindresorhus/ora/blob/main/index.js#L416C2-L416C50
167+
// export {default as spinners} from 'cli-spinners'
168+
socketModifyPlugin({
169+
find: /(?<=ora[^.]+\.spinners\s*=\s*)[$\w]+/g,
170+
replace(match) {
171+
return (
172+
new RegExp(`(?<=${escapeRegExp(match)}\\s*=\\s*)[$\\w]+`).exec(
173+
this.input
174+
)?.[0] ?? match
175+
)
176+
}
177+
}),
178+
commonjs({
179+
ignoreDynamicRequires: true,
180+
ignoreGlobal: true,
181+
ignoreTryCatch: true,
182+
defaultIsModuleExports: true,
183+
transformMixedEsModules: true,
184+
extensions: ['.cjs', '.js', '.ts', `.ts${ENTRY_SUFFIX}`]
185+
}),
186+
...(extendConfig.plugins ?? [])
187+
]
188+
}
189+
190+
const output = (
191+
Array.isArray(config.output)
192+
? config.output
193+
: config.output
194+
? [config.output]
195+
: []
196+
).map(o => ({
197+
...o,
198+
chunkFileNames: '[name].js',
199+
manualChunks(id) {
200+
if (id.includes('/node_modules/')) {
201+
return 'vendor'
202+
}
203+
}
204+
}))
205+
206+
// Replace hard-coded absolute paths in source with hard-coded relative paths.
207+
const replacePlugin = replace({
208+
delimiters: ['(?<=["\'])', '/'],
209+
preventAssignment: false,
210+
values: {
211+
[rootPath]: '../'
212+
}
213+
})
214+
215+
const replaceOutputPlugin = {
216+
name: replacePlugin.name,
217+
renderChunk: replacePlugin.renderChunk
218+
}
219+
220+
for (const o of output) {
221+
o.plugins = [
222+
...(Array.isArray(o.plugins) ? o.plugins : []),
223+
replaceOutputPlugin
224+
]
225+
}
226+
227+
config.output = output
228+
return config
229+
}

.config/rollup.dist.config.mjs

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
import { chmodSync, readFileSync, writeFileSync } from 'node:fs'
2+
import path from 'node:path'
3+
import { fileURLToPath } from 'node:url'
4+
5+
import { loadJSON } from '../scripts/files.js'
6+
import { hasKeys } from '../scripts/objects.js'
7+
import { toSortedObject } from '../scripts/sorts.js'
8+
import { formatObject } from '../scripts/strings.js'
9+
10+
import baseConfig from './rollup.base.config.mjs'
11+
12+
const __dirname = fileURLToPath(new URL('.', import.meta.url))
13+
14+
const rootPath = path.resolve(__dirname, '..')
15+
const depStatsPath = path.join(rootPath, '.dep-stats.json')
16+
const distPath = path.join(rootPath, 'dist')
17+
const srcPath = path.join(rootPath, 'src')
18+
19+
const pkgJSONPath = path.resolve(rootPath, 'package.json')
20+
const pkgJSON = loadJSON(pkgJSONPath)
21+
22+
export default () => {
23+
const config = baseConfig({
24+
input: {
25+
cli: `${srcPath}/cli.ts`,
26+
'npm-cli': `${srcPath}/shadow/npm-cli.ts`,
27+
'npx-cli': `${srcPath}/shadow/npx-cli.ts`,
28+
'npm-injection': `${srcPath}/shadow/npm-injection.ts`
29+
},
30+
output: [
31+
{
32+
dir: 'dist',
33+
entryFileNames: '[name].js',
34+
format: 'cjs',
35+
exports: 'auto',
36+
externalLiveBindings: false,
37+
freeze: false
38+
}
39+
],
40+
plugins: [
41+
{
42+
writeBundle() {
43+
const { '@cyclonedx/cdxgen': cdxgenRange, synp: synpRange } =
44+
pkgJSON.dependencies
45+
const { depStats } = config.meta
46+
47+
// Manually add @cyclonedx/cdxgen and synp as they are not directly
48+
// referenced in the code but used through spawned processes.
49+
depStats.dependencies['@cyclonedx/cdxgen'] = cdxgenRange
50+
depStats.dependencies.synp = synpRange
51+
depStats.external['@cyclonedx/cdxgen'] = cdxgenRange
52+
depStats.external.synp = synpRange
53+
54+
try {
55+
// Remove transitives from dependencies
56+
const oldDepStats = loadJSON(depStatsPath)
57+
for (const key of Object.keys(oldDepStats.transitives)) {
58+
if (pkgJSON.dependencies[key]) {
59+
depStats.transitives[key] = pkgJSON.dependencies[key]
60+
depStats.external[key] = pkgJSON.dependencies[key]
61+
delete depStats.dependencies[key]
62+
}
63+
}
64+
} catch {}
65+
66+
depStats.dependencies = toSortedObject(depStats.dependencies)
67+
depStats.devDependencies = toSortedObject(depStats.devDependencies)
68+
depStats.esm = toSortedObject(depStats.esm)
69+
depStats.external = toSortedObject(depStats.external)
70+
depStats.transitives = toSortedObject(depStats.transitives)
71+
72+
// Write dep stats
73+
writeFileSync(depStatsPath, `${formatObject(depStats)}\n`, 'utf8')
74+
75+
// Make dist files chmod +x
76+
chmodSync(path.join(distPath, 'cli.js'), 0o755)
77+
chmodSync(path.join(distPath, 'npm-cli.js'), 0o755)
78+
chmodSync(path.join(distPath, 'npx-cli.js'), 0o755)
79+
80+
// Update dependencies with additional inlined modules
81+
writeFileSync(
82+
pkgJSONPath,
83+
readFileSync(pkgJSONPath, 'utf8').replace(
84+
/(?<="dependencies":\s*)\{[^\}]*\}/,
85+
() => {
86+
const deps = {
87+
...depStats.dependencies,
88+
...depStats.transitives
89+
}
90+
const formatted = formatObject(deps, 4)
91+
return hasKeys(deps) ? formatted.replace('}', ' }') : formatted
92+
}
93+
),
94+
'utf8'
95+
)
96+
}
97+
}
98+
]
99+
})
100+
101+
return config
102+
}

.config/rollup.test.config.mjs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import path from 'node:path'
2+
import { fileURLToPath } from 'node:url'
3+
4+
import baseConfig from './rollup.base.config.mjs'
5+
6+
const __dirname = fileURLToPath(new URL('.', import.meta.url))
7+
8+
const rootPath = path.resolve(__dirname, '..')
9+
const srcPath = path.join(rootPath, 'src')
10+
11+
export default () =>
12+
baseConfig({
13+
input: {
14+
'path-resolve': `${srcPath}/utils/path-resolve.ts`
15+
},
16+
output: [
17+
{
18+
dir: 'test/dist',
19+
entryFileNames: '[name].js',
20+
format: 'cjs',
21+
exports: 'auto',
22+
externalLiveBindings: false,
23+
freeze: false
24+
}
25+
]
26+
})

0 commit comments

Comments
 (0)