@jcoreio/toolchain 1.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/.eslintrc.js +6 -0
  2. package/bin/commitizen +5 -0
  3. package/bin/commitlint +5 -0
  4. package/bin/cz +5 -0
  5. package/bin/eslint +5 -0
  6. package/bin/git-cz +5 -0
  7. package/bin/lint-fix.cjs +8 -0
  8. package/bin/lint-staged +5 -0
  9. package/bin/prettier +5 -0
  10. package/bin/resolveBin.cjs +8 -0
  11. package/bin/semantic-release +5 -0
  12. package/commitizen.cjs +1 -0
  13. package/commitlint.config.cjs +11 -0
  14. package/eslint.config.cjs +8 -0
  15. package/eslint.extends.cjs +54 -0
  16. package/githooks/applypatch-msg +3 -0
  17. package/githooks/commit-msg +3 -0
  18. package/githooks/post-applypatch +3 -0
  19. package/githooks/post-checkout +3 -0
  20. package/githooks/post-commit +3 -0
  21. package/githooks/post-merge +3 -0
  22. package/githooks/post-receive +3 -0
  23. package/githooks/post-rewrite +3 -0
  24. package/githooks/post-update +3 -0
  25. package/githooks/pre-applypatch +3 -0
  26. package/githooks/pre-auto-gc +3 -0
  27. package/githooks/pre-commit +3 -0
  28. package/githooks/pre-merge-commit +3 -0
  29. package/githooks/pre-push +3 -0
  30. package/githooks/pre-rebase +3 -0
  31. package/githooks/pre-receive +3 -0
  32. package/githooks/prepare-commit-msg +3 -0
  33. package/githooks/push-to-checkout +3 -0
  34. package/githooks/runHook.cjs +32 -0
  35. package/githooks.cjs +5 -0
  36. package/lint-staged.config.cjs +20 -0
  37. package/package.json +60 -0
  38. package/plugins/buildDistPackageJson.cjs +7 -0
  39. package/plugins/compile.cjs +21 -0
  40. package/plugins/formatExtensions.cjs +12 -0
  41. package/plugins/getConfigFiles.cjs +57 -0
  42. package/plugins/getEslintExtends.cjs +1 -0
  43. package/plugins/lintExtensions.cjs +1 -0
  44. package/plugins/sourceExtensions.cjs +1 -0
  45. package/prettier.config.cjs +5 -0
  46. package/release.config.cjs +16 -0
  47. package/scripts/bootstrap/bootstrapConfigFiles.cjs +18 -0
  48. package/scripts/bootstrap/bootstrapEslintConfigs.cjs +30 -0
  49. package/scripts/bootstrap/bootstrapGitignore.cjs +37 -0
  50. package/scripts/bootstrap/bootstrapMoveTypeDefs.cjs +14 -0
  51. package/scripts/bootstrap/bootstrapProjectPackageJson.cjs +76 -0
  52. package/scripts/bootstrap/bootstrapRemoveDevDeps.cjs +110 -0
  53. package/scripts/bootstrap/bootstrapRemoveFiles.cjs +50 -0
  54. package/scripts/bootstrap/installGitHooks.cjs +31 -0
  55. package/scripts/bootstrap.cjs +48 -0
  56. package/scripts/build.cjs +66 -0
  57. package/scripts/check.cjs +19 -0
  58. package/scripts/clean.cjs +6 -0
  59. package/scripts/coverage.cjs +12 -0
  60. package/scripts/format.cjs +4 -0
  61. package/scripts/init.cjs +55 -0
  62. package/scripts/lint-fix.cjs +4 -0
  63. package/scripts/lint.cjs +4 -0
  64. package/scripts/open-coverage.cjs +7 -0
  65. package/scripts/preinstall/preinstallRemoveDevDeps.cjs +65 -0
  66. package/scripts/preinstall/preinstallRemoveFiles.cjs +50 -0
  67. package/scripts/preinstall/preinstallUpdateProjectPackageJson.cjs +39 -0
  68. package/scripts/preinstall.cjs +35 -0
  69. package/scripts/prepublish.cjs +11 -0
  70. package/scripts/runEslint.cjs +34 -0
  71. package/scripts/runPrettier.cjs +27 -0
  72. package/scripts/test.cjs +12 -0
  73. package/scripts/toolchain.cjs +82 -0
  74. package/util/ChdirFs.cjs +50 -0
  75. package/util/execa.cjs +72 -0
  76. package/util/findUps.cjs +44 -0
  77. package/util/getPlugins.cjs +21 -0
  78. package/util/getPluginsArraySync.cjs +14 -0
  79. package/util/getPluginsAsyncFunction.cjs +12 -0
  80. package/util/getPluginsObject.cjs +12 -0
  81. package/util/glob.cjs +6 -0
  82. package/util/hasTSSourcesSync.cjs +7 -0
  83. package/util/ini.cjs +36 -0
  84. package/util/once.cjs +6 -0
  85. package/util/projectFs.cjs +4 -0
  86. package/util/sortDeps.cjs +21 -0
  87. package/util/sortPlugins.cjs +67 -0
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require('../util/projectFs.cjs')
4
+
5
+ async function preinstall(args = []) {
6
+ const preinstallUpdateProjectPackageJson = require('./preinstall/preinstallUpdateProjectPackageJson.cjs')
7
+
8
+ await Promise.all(
9
+ require('./preinstall/preinstallRemoveFiles.cjs').map(async (file) => {
10
+ const exists = await fs.pathExists(file)
11
+ if (exists) {
12
+ await fs.remove(file)
13
+ // eslint-disable-next-line no-console
14
+ console.error('removed', file)
15
+ }
16
+ })
17
+ )
18
+
19
+ await preinstallUpdateProjectPackageJson()
20
+ }
21
+
22
+ exports.description =
23
+ 'run this script before installing toolchains in a project'
24
+ exports.run = preinstall
25
+
26
+ if (require.main === module) {
27
+ preinstall().then(
28
+ () => process.exit(0),
29
+ (error) => {
30
+ // eslint-disable-next-line no-console
31
+ console.error(error.stack)
32
+ process.exit(error.exitCode != null ? error.exitCode : 1)
33
+ }
34
+ )
35
+ }
@@ -0,0 +1,11 @@
1
+ const check = require('./check.cjs')
2
+ const coverage = require('./coverage.cjs')
3
+ const build = require('./build.cjs')
4
+
5
+ exports.run = async function (args = []) {
6
+ await check.run()
7
+ await coverage.run()
8
+ await build.run()
9
+ }
10
+
11
+ exports.description = 'run check, coverage, and build'
@@ -0,0 +1,34 @@
1
+ const fs = require('../util/projectFs.cjs')
2
+ const execa = require('../util/execa.cjs')
3
+ const getPluginsArraySync = require('../util/getPluginsArraySync.cjs')
4
+
5
+ async function eslintArgs() {
6
+ return [
7
+ ...((await fs.pathExists('.eslintignore'))
8
+ ? ['--ignore-path', '.eslintignore']
9
+ : (await fs.pathExists('.gitignore'))
10
+ ? ['--ignore-path', '.gitignore']
11
+ : []),
12
+ '--ignore-pattern',
13
+ 'flow-typed/',
14
+ '--ext',
15
+ getPluginsArraySync('lintExtensions').join(','),
16
+ ]
17
+ }
18
+
19
+ async function runEslint(args = []) {
20
+ await execa('eslint', [...args, ...(await eslintArgs())])
21
+ }
22
+ exports.runEslint = runEslint
23
+
24
+ async function eslintCheck(args = []) {
25
+ if (args.length === 0) args = ['.']
26
+ await runEslint(args)
27
+ }
28
+ exports.eslintCheck = eslintCheck
29
+
30
+ async function eslintFix(args = []) {
31
+ if (args.length === 0) args = ['.']
32
+ await runEslint(['--fix', ...args])
33
+ }
34
+ exports.eslintFix = eslintFix
@@ -0,0 +1,27 @@
1
+ const fs = require('../util/projectFs.cjs')
2
+ const execa = require('../util/execa.cjs')
3
+
4
+ async function prettierArgs() {
5
+ return (await fs.pathExists('.prettierignore'))
6
+ ? ['--ignore-path', '.prettierignore']
7
+ : (await fs.pathExists('.gitignore'))
8
+ ? ['--ignore-path', '.gitignore']
9
+ : []
10
+ }
11
+
12
+ async function runPrettier(args = []) {
13
+ await execa('prettier', [...(await prettierArgs()), ...args])
14
+ }
15
+ exports.runPrettier = runPrettier
16
+
17
+ async function prettierCheck(args = []) {
18
+ if (args.length === 0) args = ['.', '!pnpm-lock.yaml']
19
+ await runPrettier(['-c', ...args])
20
+ }
21
+ exports.prettierCheck = prettierCheck
22
+
23
+ async function prettierFormat(args = []) {
24
+ if (args.length === 0) args = ['.', '!pnpm-lock.yaml']
25
+ await runPrettier(['--write', ...args])
26
+ }
27
+ exports.prettierFormat = prettierFormat
@@ -0,0 +1,12 @@
1
+ const getPlugins = require('../util/getPlugins.cjs')
2
+ const getPluginsAsyncFunction = require('../util/getPluginsAsyncFunction.cjs')
3
+
4
+ exports.run = async function (args = []) {
5
+ if (!getPlugins('test').length) {
6
+ throw new Error(
7
+ 'missing test toolchain, install @jcoreio/toolchain-mocha (there may be alternatives in the future)'
8
+ )
9
+ }
10
+ await getPluginsAsyncFunction('test')(args)
11
+ }
12
+ exports.description = 'run tests'
@@ -0,0 +1,82 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { name, version } = require('../package.json')
4
+ const chalk = require('chalk')
5
+
6
+ const scripts = {
7
+ bootstrap: require('./bootstrap.cjs'),
8
+ build: require('./build.cjs'),
9
+ check: require('./check.cjs'),
10
+ clean: require('./clean.cjs'),
11
+ coverage: require('./coverage.cjs'),
12
+ format: require('./format.cjs'),
13
+ init: require('./init.cjs'),
14
+ preinstall: require('./preinstall.cjs'),
15
+ lint: require('./lint.cjs'),
16
+ 'lint:fix': require('./lint-fix.cjs'),
17
+ 'open:coverage': require('./open-coverage.cjs'),
18
+ prepublish: require('./prepublish.cjs'),
19
+ test: require('./test.cjs'),
20
+ version: {
21
+ description: `print version of ${name}`,
22
+ run: () => {
23
+ // eslint-disable-next-line no-console
24
+ console.log(`${name}@${version}`)
25
+ },
26
+ },
27
+ }
28
+
29
+ exports.scripts = scripts
30
+
31
+ async function toolchain(command, args) {
32
+ if (!command) {
33
+ /* eslint-disable no-console */
34
+ console.error('Usage: toolchain <command> <arguments...>\n')
35
+ console.error('Available commands:')
36
+ for (const script of Object.keys(scripts).sort()) {
37
+ console.error(
38
+ chalk` {bold ${script.padEnd(20)}}${scripts[script].description}`
39
+ )
40
+ }
41
+ /* eslint-enable no-console */
42
+ process.exit(1)
43
+ }
44
+ const script = scripts[command]
45
+ if (!script) {
46
+ console.error('Unknown command:', command) // eslint-disable-line no-console
47
+ process.exit(1)
48
+ }
49
+
50
+ if (script !== scripts.version) {
51
+ console.error(chalk`{bold ${name}@${version}}`) // eslint-disable-line no-console
52
+ }
53
+
54
+ try {
55
+ await script.run(args)
56
+ } catch (error) {
57
+ const { exitCode } = error
58
+ if (typeof exitCode === 'number' && exitCode !== 0) {
59
+ console.error(error.message) // eslint-disable-line no-console
60
+ } else {
61
+ console.error(error.stack) // eslint-disable-line no-console
62
+ }
63
+ throw error
64
+ }
65
+ }
66
+ exports.toolchain = toolchain
67
+
68
+ if (require.main === module) {
69
+ toolchain(process.argv[2], process.argv.slice(3)).then(
70
+ () => {
71
+ process.exit(0)
72
+ },
73
+ (error) => {
74
+ const { exitCode } = error
75
+ if (typeof exitCode === 'number' && exitCode !== 0) {
76
+ process.exit(exitCode)
77
+ } else {
78
+ process.exit(1)
79
+ }
80
+ }
81
+ )
82
+ }
@@ -0,0 +1,50 @@
1
+ const fs = require('fs-extra')
2
+ const { resolve } = require('path')
3
+
4
+ function ChdirFs(cwd) {
5
+ return {
6
+ copy: (src, dest, ...args) =>
7
+ fs.copy(resolve(cwd, src), resolve(cwd, dest), ...args),
8
+ copySync: (src, dest, ...args) =>
9
+ fs.copySync(resolve(cwd, src), resolve(cwd, dest), ...args),
10
+ lstat: (path, ...args) => fs.lstat(resolve(cwd, path), ...args),
11
+ stat: (path, ...args) => fs.stat(resolve(cwd, path), ...args),
12
+ lstatSync: (path, ...args) => fs.lstatSync(resolve(cwd, path), ...args),
13
+ statSync: (path, ...args) => fs.statSync(resolve(cwd, path), ...args),
14
+ pathExists: (path, ...args) => fs.pathExists(resolve(cwd, path), ...args),
15
+ pathExistsSync: (path, ...args) =>
16
+ fs.pathExistsSync(resolve(cwd, path), ...args),
17
+ ensureFile: (path, ...args) => fs.ensureFile(resolve(cwd, path), ...args),
18
+ ensureFileSync: (path, ...args) =>
19
+ fs.ensureFileSync(resolve(cwd, path), ...args),
20
+ move: (src, dest, ...args) =>
21
+ fs.move(resolve(cwd, src), resolve(cwd, dest), ...args),
22
+ moveSync: (src, dest, ...args) =>
23
+ fs.moveSync(resolve(cwd, src), resolve(cwd, dest), ...args),
24
+ readFile: (path, ...args) => fs.readFile(resolve(cwd, path), ...args),
25
+ readFileSync: (path, ...args) =>
26
+ fs.readFileSync(resolve(cwd, path), ...args),
27
+ readJson: (path, ...args) => fs.readJson(resolve(cwd, path), ...args),
28
+ readJsonSync: (path, ...args) =>
29
+ fs.readJsonSync(resolve(cwd, path), ...args),
30
+ writeFile: (path, ...args) => fs.writeFile(resolve(cwd, path), ...args),
31
+ writeFileSync: (path, ...args) =>
32
+ fs.writeFileSync(resolve(cwd, path), ...args),
33
+ writeJson: (path, ...args) => fs.writeJson(resolve(cwd, path), ...args),
34
+ writeJsonSync: (path, ...args) =>
35
+ fs.writeJsonSync(resolve(cwd, path), ...args),
36
+ mkdirs: (path, ...args) => fs.mkdirs(resolve(cwd, path), ...args),
37
+ mkdirsSync: (path, ...args) => fs.mkdirsSync(resolve(cwd, path), ...args),
38
+ remove: (path, ...args) => fs.remove(resolve(cwd, path), ...args),
39
+ removeSync: (path, ...args) => fs.removeSync(resolve(cwd, path), ...args),
40
+ readdir: (path, ...args) => fs.readdir(resolve(cwd, path), ...args),
41
+ readdirSync: (path, ...args) => fs.readdirSync(resolve(cwd, path), ...args),
42
+ readlink: (path, ...args) => fs.readlink(resolve(cwd, path), ...args),
43
+ readlinkSync: (path, ...args) =>
44
+ fs.readlinkSync(resolve(cwd, path), ...args),
45
+ realpath: (path, ...args) => fs.realpath(resolve(cwd, path), ...args),
46
+ realpathSync: (path, ...args) =>
47
+ fs.realpathSync(resolve(cwd, path), ...args),
48
+ }
49
+ }
50
+ module.exports = ChdirFs
package/util/execa.cjs ADDED
@@ -0,0 +1,72 @@
1
+ const Path = require('path')
2
+ const execa = require('execa')
3
+ const chalk = require('chalk')
4
+ const { projectDir, toolchainPackages } = require('./findUps.cjs')
5
+
6
+ function formatArg(arg) {
7
+ if (/^[-_a-z0-9=./]+$/i.test(arg)) return arg
8
+ return `'${arg.replace(/'/g, "'\\''")}'`
9
+ }
10
+
11
+ function extractCommand(command) {
12
+ command = Path.basename(command).trim()
13
+ const match = /^\S+/.exec(command)
14
+ return match ? match[0] : command
15
+ }
16
+
17
+ module.exports = async function defaultExeca(command, args, options, ...rest) {
18
+ if (args instanceof Object && !Array.isArray(args)) {
19
+ options = args
20
+ args = []
21
+ } else if (!options) {
22
+ options = {}
23
+ }
24
+
25
+ // eslint-disable-next-line no-console
26
+ console.error(
27
+ chalk`{gray.bold $ ${command}${
28
+ args ? ' ' + args.map(formatArg).join(' ') : ''
29
+ }}`
30
+ )
31
+
32
+ const opts = {
33
+ stdio: 'inherit',
34
+ cwd: projectDir,
35
+ ...options,
36
+ env: {
37
+ ...process.env,
38
+ ...options.env,
39
+ PATH: [
40
+ Path.join(projectDir, 'node_modules', '.bin'),
41
+ ...toolchainPackages.map((pkg) =>
42
+ Path.join(projectDir, 'node_modules', pkg, 'node_modules', '.bin')
43
+ ),
44
+ (options.env || process.env).PATH,
45
+ ].join(Path.delimiter),
46
+ },
47
+ }
48
+
49
+ const child = execa(command, args, opts, ...rest)
50
+ child.then(
51
+ (result) => {
52
+ // eslint-disable-next-line no-console
53
+ console.error(
54
+ chalk`{green ✔} {bold ${extractCommand(command)}} exited with code 0`
55
+ )
56
+ },
57
+ (error) => {
58
+ const { code, signal } = error
59
+ if (code) {
60
+ error.message = chalk`{red ✖} {bold ${extractCommand(
61
+ command
62
+ )}} exited with code ${code}`
63
+ }
64
+ if (signal) {
65
+ error.message = chalk`{red ✖} {bold ${extractCommand(
66
+ command
67
+ )}} was killed with signal ${signal}`
68
+ }
69
+ }
70
+ )
71
+ return child
72
+ }
@@ -0,0 +1,44 @@
1
+ const findUp = require('find-up')
2
+ const Path = require('path')
3
+ const fs = require('fs-extra')
4
+ const once = require('./once.cjs')
5
+ const { name } = require('../package.json')
6
+
7
+ const findGitDir = once(function findGitDir(
8
+ cwd = process.env.INIT_CWD || process.cwd()
9
+ ) {
10
+ return findUp.sync('.git', { cwd, type: 'directory' })
11
+ })
12
+ exports.findGitDir = findGitDir
13
+
14
+ let cwd = process.cwd()
15
+
16
+ const nodeModulesMatch = /\/node_modules(\/|$)/.exec(cwd)
17
+ if (nodeModulesMatch) cwd = cwd.substring(0, nodeModulesMatch.index)
18
+
19
+ const packageJsonFile = findUp.sync('package.json', { cwd, type: 'file' })
20
+ if (!packageJsonFile) {
21
+ throw new Error(
22
+ `failed to find project package.json in a parent directory of ${cwd}`
23
+ )
24
+ }
25
+ exports.packageJsonFile = packageJsonFile
26
+ const packageJson = (exports.packageJson = fs.readJsonSync(packageJsonFile))
27
+ exports.projectDir = Path.dirname(packageJsonFile)
28
+
29
+ exports.toolchainPackages = [
30
+ ...Object.keys(packageJson.dependencies || {}),
31
+ ...Object.keys(packageJson.devDependencies || {}),
32
+ ].filter((dep) => dep.startsWith(name))
33
+
34
+ let toolchainConfigFile
35
+ try {
36
+ toolchainConfigFile = require.resolve(
37
+ Path.join(exports.projectDir, 'toolchain.config.cjs')
38
+ )
39
+ } catch (error) {
40
+ // ignore
41
+ }
42
+ exports.toolchainConfig = toolchainConfigFile
43
+ ? require(toolchainConfigFile)
44
+ : {}
@@ -0,0 +1,21 @@
1
+ const Path = require('path')
2
+ const sortPlugins = require('./sortPlugins.cjs')
3
+ const { projectDir, toolchainPackages } = require('./findUps.cjs')
4
+
5
+ function getPlugins(name) {
6
+ const plugins = {}
7
+ for (const pkg of toolchainPackages) {
8
+ let path
9
+ try {
10
+ path = require.resolve(Path.join(pkg, 'plugins', `${name}.cjs`), {
11
+ paths: [projectDir],
12
+ })
13
+ } catch (error) {
14
+ continue
15
+ }
16
+ plugins[pkg] = require(path)
17
+ }
18
+ return sortPlugins(plugins)
19
+ }
20
+
21
+ module.exports = getPlugins
@@ -0,0 +1,14 @@
1
+ const getPlugins = require('./getPlugins.cjs')
2
+
3
+ function getPluginsArraySync(name, ...args) {
4
+ const plugins = getPlugins(name)
5
+ const result = []
6
+ for (const plugin of plugins) {
7
+ const output = plugin(...args)
8
+ if (Array.isArray(output)) output.forEach((el) => result.push(el))
9
+ else if (output != null) result.push(output)
10
+ }
11
+ return result
12
+ }
13
+
14
+ module.exports = getPluginsArraySync
@@ -0,0 +1,12 @@
1
+ const getPlugins = require('./getPlugins.cjs')
2
+
3
+ function getPluginsAsyncFunction(name) {
4
+ const plugins = getPlugins(name)
5
+ return async function (...args) {
6
+ for (const plugin of plugins) {
7
+ await plugin(...args)
8
+ }
9
+ }
10
+ }
11
+
12
+ module.exports = getPluginsAsyncFunction
@@ -0,0 +1,12 @@
1
+ const getPlugins = require('./getPlugins.cjs')
2
+
3
+ async function getPluginsObject(name, ...args) {
4
+ const plugins = getPlugins(name)
5
+ const result = {}
6
+ for (const plugin of plugins) {
7
+ Object.assign(result, await plugin(...args))
8
+ }
9
+ return result
10
+ }
11
+
12
+ module.exports = getPluginsObject
package/util/glob.cjs ADDED
@@ -0,0 +1,6 @@
1
+ const _glob = require('util').promisify(require('glob'))
2
+ const { projectDir } = require('./findUps.cjs')
3
+
4
+ const glob = (what, options) => _glob(what, { cwd: projectDir, ...options })
5
+
6
+ module.exports = glob
@@ -0,0 +1,7 @@
1
+ const fs = require('./projectFs.cjs')
2
+ const once = require('./once.cjs')
3
+
4
+ module.exports = once(function hasTSSourcesSync() {
5
+ const files = fs.readdirSync('src')
6
+ return files.find((f) => /\.tsx?$/.test(f) && !/\.d\.tsx?$/.test(f)) != null
7
+ })
package/util/ini.cjs ADDED
@@ -0,0 +1,36 @@
1
+ var REG_GROUP = /^\s*\[(.+?)\]\s*$/
2
+ var REG_ITEM = /^\s*([^#[].*)\s*$/
3
+
4
+ function parse(string) {
5
+ const object = {}
6
+ const lines = string.split('\n')
7
+ let group
8
+ let match
9
+
10
+ for (const line of lines) {
11
+ if ((match = line.match(REG_GROUP)))
12
+ object[match[1]] = group = object[match[1]] || []
13
+ else if (group && (match = line.match(REG_ITEM))) group.push(match[1])
14
+ }
15
+
16
+ return object
17
+ }
18
+
19
+ exports.parse = parse
20
+
21
+ function stringify(ini) {
22
+ const lines = []
23
+ for (const key in ini) {
24
+ if (Object.prototype.hasOwnProperty.call(ini, key)) {
25
+ const group = ini[key]
26
+ if (Array.isArray(group)) {
27
+ lines.push(`[${key}]`)
28
+ for (const item of group) lines.push(item)
29
+ lines.push('')
30
+ }
31
+ }
32
+ }
33
+ return lines.join('\n')
34
+ }
35
+
36
+ exports.stringify = stringify
package/util/once.cjs ADDED
@@ -0,0 +1,6 @@
1
+ module.exports = function once(fn) {
2
+ let result
3
+ return function onceified() {
4
+ return (result || (result = [fn.apply(this, arguments)]))[0]
5
+ }
6
+ }
@@ -0,0 +1,4 @@
1
+ const ChdirFs = require('./ChdirFs.cjs')
2
+ const { projectDir } = require('./findUps.cjs')
3
+
4
+ module.exports = ChdirFs(projectDir)
@@ -0,0 +1,21 @@
1
+ function sortedObject(obj) {
2
+ return Object.fromEntries(
3
+ Object.keys(obj)
4
+ .sort()
5
+ .map((key) => [key, obj[key]])
6
+ )
7
+ }
8
+
9
+ function sortDeps(packageJson) {
10
+ for (const section of [
11
+ 'dependencies',
12
+ 'devDependencies',
13
+ 'peerDependencies',
14
+ 'optionalDependencies',
15
+ ]) {
16
+ if (packageJson[section])
17
+ packageJson[section] = sortedObject(packageJson[section])
18
+ }
19
+ }
20
+
21
+ module.exports = sortDeps
@@ -0,0 +1,67 @@
1
+ const toposort = require('toposort')
2
+
3
+ function asArray(x) {
4
+ return Array.isArray(x) ? x : x ? [x] : []
5
+ }
6
+
7
+ function normalizeDef(def) {
8
+ const plugin = Array.isArray(def) ? def[0] : def
9
+ const options = Array.isArray(def) ? def[1] : {}
10
+ return {
11
+ plugin,
12
+ before: asArray(options.before),
13
+ after: asArray(options.after),
14
+ insteadOf: asArray(options.insteadOf),
15
+ }
16
+ }
17
+
18
+ function sortPlugins(defs) {
19
+ const plugins = new Map()
20
+ const edges = []
21
+ const excluded = new Set()
22
+
23
+ const makeId = (pkg, i) => JSON.stringify({ pkg, i })
24
+
25
+ for (const [pkg, pkgDefs] of Object.entries(defs)) {
26
+ for (let i = 0; i < pkgDefs.length; i++) {
27
+ const id = makeId(pkg, i)
28
+ const def = pkgDefs[i]
29
+ const { plugin, before, after, insteadOf } = normalizeDef(def)
30
+ plugins.set(id, plugin)
31
+
32
+ if (before.length) {
33
+ for (const other of before) {
34
+ if (!defs[other]) continue
35
+ for (let i = 0; i < defs[other].length; i++) {
36
+ edges.push([id, makeId(other, i)])
37
+ }
38
+ }
39
+ }
40
+ if (after.length) {
41
+ for (const other of after) {
42
+ if (!defs[other]) continue
43
+ for (let i = 0; i < defs[other].length; i++) {
44
+ edges.push([makeId(other, i), id])
45
+ }
46
+ }
47
+ }
48
+ for (const other of insteadOf) {
49
+ if (!defs[other]) continue
50
+ for (let i = 0; i < defs[other].length; i++) {
51
+ excluded.add(makeId(other, i))
52
+ }
53
+ }
54
+ }
55
+ }
56
+ const sorted = toposort(edges)
57
+ const sortedSet = new Set(sorted)
58
+ for (const [pkg, pkgDefs] of Object.entries(defs)) {
59
+ for (let i = 0; i < pkgDefs.length; i++) {
60
+ const id = makeId(pkg, i)
61
+ if (!sortedSet.has(id)) sorted.push(id)
62
+ }
63
+ }
64
+ return sorted.filter((id) => !excluded.has(id)).map((id) => plugins.get(id))
65
+ }
66
+
67
+ module.exports = sortPlugins