@jcoreio/toolchain 3.11.0 → 4.0.0

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.
package/.eslintrc.js CHANGED
@@ -1,5 +1,5 @@
1
1
  module.exports = {
2
- extends: [require.resolve('./eslint.config.cjs')],
2
+ extends: [require.resolve('./eslintConfig.cjs')],
3
3
  env: {
4
4
  node: true,
5
5
  },
@@ -4,7 +4,7 @@ const execa = require('../util/execa.cjs')
4
4
 
5
5
  module.exports = async function runHook(hookName) {
6
6
  try {
7
- const gitDir = findGitDir()
7
+ const gitDir = findGitDir(process.env.INIT_CWD)
8
8
  if (!gitDir) {
9
9
  throw new Error(`failed to find .git directory`)
10
10
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jcoreio/toolchain",
3
- "version": "3.11.0",
3
+ "version": "4.0.0",
4
4
  "description": "base JS build toolchain",
5
5
  "repository": {
6
6
  "type": "git",
@@ -24,14 +24,14 @@
24
24
  "fs-extra": "^10.0.0",
25
25
  "glob": "^7.2.0",
26
26
  "json5": "^2.2.1",
27
- "lint-staged": "^12.1.4",
28
- "lodash": "^4.17.21",
27
+ "lint-staged": "^15.2.2",
29
28
  "open": "^8.4.0",
30
29
  "prettier": "^2.5.1",
31
30
  "prompts": "^2.4.2",
32
31
  "resolve-bin": "^1.0.0",
33
32
  "semver": "^7.5.3",
34
33
  "toposort": "^2.0.2",
34
+ "yaml": "^2.4.1",
35
35
  "zod": "^3.21.4"
36
36
  },
37
37
  "toolchainManaged": {
@@ -1,9 +1,10 @@
1
+ const mapValues = require('../util/mapValues.cjs')
2
+
1
3
  module.exports = [
2
4
  async function buildDistPackageJson(packageJson) {
3
5
  delete packageJson.devDependencies
4
6
  delete packageJson.scripts
5
7
  delete packageJson.config
6
- const mapValues = require('lodash/mapValues')
7
8
 
8
9
  function replaceDist(path) {
9
10
  return path.replace(/^(\.\/)?dist\//, '$1')
@@ -17,18 +17,30 @@ module.exports = [
17
17
  async function getConfigFiles() {
18
18
  const { env, rules } = (await getRootEslintConfig()) || {}
19
19
  const files = {
20
- '.eslintrc.cjs': dedent`
20
+ '.eslintrc.cjs': (prev) =>
21
+ prev
22
+ ? prev.replace(
23
+ new RegExp(`${name}/eslint\\.config\\.cjs`, 'g'),
24
+ `${name}/eslintConfig.cjs`
25
+ )
26
+ : dedent`
21
27
  /* eslint-env node, es2018 */
22
28
  module.exports = {
23
- extends: [require.resolve('${name}/eslint.config.cjs')],${
24
- env
25
- ? `\nenv: ${JSON.stringify(env, null, 2).replace(/\n/gm, '\n ')},`
26
- : ''
27
- }${
28
- rules
29
- ? `\nrules: ${JSON.stringify(rules, null, 2).replace(/\n/gm, '\n ')}`
30
- : ''
31
- }
29
+ extends: [require.resolve('${name}/eslintConfig.cjs')],${
30
+ env
31
+ ? `\nenv: ${JSON.stringify(env, null, 2).replace(
32
+ /\n/gm,
33
+ '\n '
34
+ )},`
35
+ : ''
36
+ }${
37
+ rules
38
+ ? `\nrules: ${JSON.stringify(rules, null, 2).replace(
39
+ /\n/gm,
40
+ '\n '
41
+ )}`
42
+ : ''
43
+ }
32
44
  }
33
45
  `,
34
46
  'toolchain.config.cjs': async (existing) => {
package/scripts/init.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- const { packageJson } = require('../util/findUps.cjs')
3
+ const { packageJson, isMonorepoRoot } = require('../util/findUps.cjs')
4
4
  const fs = require('../util/projectFs.cjs')
5
5
  const execa = require('../util/execa.cjs')
6
6
  const hasTSFiles = require('../util/hasTSFiles.cjs')
@@ -69,6 +69,7 @@ async function init(args = []) {
69
69
  await execa('pnpm', [
70
70
  'add',
71
71
  '-D',
72
+ ...(isMonorepoRoot ? ['-w'] : []),
72
73
  isTest ? '../packages/base' : `${name}@^${version}`,
73
74
  ...(isTest
74
75
  ? [...selectedToolchains].map((t) =>
@@ -4,15 +4,15 @@ const getPluginsAsyncFunction = require('../../util/getPluginsAsyncFunction.cjs'
4
4
  const fs = require('../../util/projectFs.cjs')
5
5
  const sortDeps = require('../../util/sortDeps.cjs')
6
6
  const semver = require('semver')
7
- const isEmpty = require('lodash/isEmpty')
8
- const pick = require('lodash/pick')
7
+ const isEmpty = require('../../util/isEmpty.cjs')
8
+ const pick = require('../../util/pick.cjs')
9
9
  const Path = require('path')
10
10
  const confirmOutputEsm = require('./confirmOutputEsm.cjs')
11
11
  const confirm = require('../../util/confirm.cjs')
12
+ const unset = require('../../util/unset.cjs')
13
+ const merge = require('../../util/merge.cjs')
12
14
 
13
15
  async function migrateProjectPackageJson() {
14
- const { merge, unset } = require('lodash')
15
-
16
16
  const packageJson = await fs.readJson('package.json')
17
17
  const devDependencies =
18
18
  packageJson.devDependencies || (packageJson.devDependencies = {})
@@ -60,7 +60,7 @@ async function migrateProjectPackageJson() {
60
60
  'scripts.test:watch',
61
61
  'scripts.test',
62
62
  'scripts.travis-deploy-once',
63
- 'scripts.tsc:wath',
63
+ 'scripts.tsc:watch',
64
64
  'scripts.tsc',
65
65
  ]) {
66
66
  unset(packageJson, path)
@@ -149,11 +149,17 @@ async function migrateProjectPackageJson() {
149
149
  const versionRange = managedSection[dep]
150
150
  if (isTest && dep.startsWith(`${name}-`)) {
151
151
  pkgSection[dep] = `link:${dep.replace(`${name}-`, '../packages/')}`
152
- } else if (
153
- !pkgSection[dep] ||
154
- !semver.satisfies(semver.minVersion(pkgSection[dep]), versionRange)
155
- ) {
156
- pkgSection[dep] = versionRange
152
+ } else {
153
+ try {
154
+ if (
155
+ !pkgSection[dep] ||
156
+ !semver.satisfies(semver.minVersion(pkgSection[dep]), versionRange)
157
+ ) {
158
+ pkgSection[dep] = versionRange
159
+ }
160
+ } catch (error) {
161
+ // ignore; package.json probably has a version like workspace:* etc
162
+ }
157
163
  }
158
164
  }
159
165
  }
@@ -46,6 +46,10 @@ module.exports = [
46
46
  '@jedwards1211/eslint-config-react',
47
47
  '@jedwards1211/eslint-config-typescript',
48
48
  '@jedwards1211/eslint-config',
49
+ '@semantic-release/commit-analyzer',
50
+ '@semantic-release/github',
51
+ '@semantic-release/npm',
52
+ '@semantic-release/release-notes-generator',
49
53
  '@typescript-eslint/eslint-plugin',
50
54
  '@typescript-eslint/parser',
51
55
  'babel-cli',
@@ -4,6 +4,11 @@ const getPluginsAsyncFunction = require('../util/getPluginsAsyncFunction.cjs')
4
4
 
5
5
  async function migrate(args = []) {
6
6
  const execa = require('../util/execa.cjs')
7
+ const {
8
+ findGitDir,
9
+ isMonorepoSubpackage,
10
+ isMonorepoRoot,
11
+ } = require('../util/findUps.cjs')
7
12
  const installGitHooks = require('./install-git-hooks.cjs')
8
13
  const migrateProjectPackageJson = require('./migrate/migrateProjectPackageJson.cjs')
9
14
  const migrateEslintConfigs = require('./migrate/migrateEslintConfigs.cjs')
@@ -12,8 +17,10 @@ async function migrate(args = []) {
12
17
  const migrateGitignore = require('./migrate/migrateGitignore.cjs')
13
18
  const hasYarnOrNpmLockfile = require('../util/hasYarnOrNpmLockfile.cjs')
14
19
 
15
- await execa('git', ['init'])
16
- await installGitHooks.run()
20
+ if (!isMonorepoSubpackage && !findGitDir()) {
21
+ await execa('git', ['init'])
22
+ await installGitHooks.run()
23
+ }
17
24
  await migrateProjectPackageJson()
18
25
  if (await hasYarnOrNpmLockfile()) {
19
26
  await execa('pnpm', ['import'])
@@ -25,7 +32,11 @@ async function migrate(args = []) {
25
32
  await getPluginsAsyncFunction('migrate')(args)
26
33
 
27
34
  if (!args.includes('--config-only')) {
28
- await execa('pnpm', ['i', '--fix-lockfile'])
35
+ await execa('pnpm', [
36
+ 'i',
37
+ '--fix-lockfile',
38
+ ...(isMonorepoRoot ? ['-w'] : []),
39
+ ])
29
40
  await execa('tc', ['format'])
30
41
  await execa('tc', ['lint:fix'])
31
42
  }
@@ -1,8 +1,7 @@
1
1
  const fs = require('../../util/projectFs.cjs')
2
+ const unset = require('../../util/unset.cjs')
2
3
 
3
4
  async function preinstallUpdateProjectPackageJson() {
4
- const { unset } = require('lodash')
5
-
6
5
  const packageJson = await fs.readJson('package.json')
7
6
  const { devDependencies } = packageJson
8
7
 
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- const { packageJson } = require('../util/findUps.cjs')
3
+ const { packageJson, isMonorepoRoot } = require('../util/findUps.cjs')
4
4
  const execa = require('../util/execa.cjs')
5
5
  const { name } = require('../package.json')
6
6
 
@@ -22,6 +22,7 @@ async function upgrade([version] = []) {
22
22
  await execa('pnpm', [
23
23
  'add',
24
24
  '-D',
25
+ ...(isMonorepoRoot ? ['-w'] : []),
25
26
  isTest ? '../packages/base' : `${name}@^${version}`,
26
27
  ...(isTest
27
28
  ? toolchains.map((t) => t.replace(`${name}-`, '../packages/'))
@@ -0,0 +1,17 @@
1
+ const isKey = require('./isKey.cjs')
2
+ const stringToPath = require('./stringToPath.cjs')
3
+
4
+ /**
5
+ * Casts `value` to a path array if it's not one.
6
+ *
7
+ * @private
8
+ * @param {*} value The value to inspect.
9
+ * @param {Object} [object] The object to query keys on.
10
+ * @returns {Array} Returns the cast property path array.
11
+ */
12
+ module.exports = function castPath(value, object) {
13
+ if (Array.isArray(value)) {
14
+ return value
15
+ }
16
+ return isKey(value, object) ? [value] : stringToPath(value)
17
+ }
package/util/findUps.cjs CHANGED
@@ -1,43 +1,88 @@
1
1
  const findUp = require('find-up')
2
2
  const Path = require('path')
3
3
  const fs = require('fs-extra')
4
- const merge = require('lodash/merge')
4
+ const merge = require('./merge.cjs')
5
5
  const once = require('./once.cjs')
6
6
  const { name } = require('../package.json')
7
7
  const configSchema = require('./configSchema.cjs')
8
8
 
9
- const findGitDir = once(function findGitDir(
10
- cwd = process.env.INIT_CWD || process.cwd()
11
- ) {
12
- return findUp.sync('.git', { cwd, type: 'directory' })
13
- })
14
- exports.findGitDir = findGitDir
15
-
16
9
  let cwd = process.cwd()
17
10
 
18
11
  const nodeModulesMatch = /\/node_modules(\/|$)/.exec(cwd)
19
12
  if (nodeModulesMatch) cwd = cwd.substring(0, nodeModulesMatch.index)
20
13
 
21
- const packageJsonFile = findUp.sync('package.json', { cwd, type: 'file' })
14
+ const packageJsonFile = (exports.packageJsonFile = findUp.sync('package.json', {
15
+ cwd,
16
+ type: 'file',
17
+ }))
22
18
  if (!packageJsonFile) {
23
19
  throw new Error(
24
20
  `failed to find project package.json in a parent directory of ${cwd}`
25
21
  )
26
22
  }
27
- exports.packageJsonFile = packageJsonFile
28
23
  const packageJson = (exports.packageJson = fs.readJsonSync(packageJsonFile))
29
24
  const projectDir = (exports.projectDir = Path.dirname(packageJsonFile))
30
25
 
26
+ const pnpmWorkspaceFile = (exports.pnpmWorkspaceFile = findUp.sync(
27
+ 'pnpm-workspace.yaml',
28
+ {
29
+ cwd,
30
+ type: 'file',
31
+ }
32
+ ))
33
+ const pnpmWorkspace = pnpmWorkspaceFile
34
+ ? require('yaml').parse(fs.readFileSync(pnpmWorkspaceFile, 'utf8'))
35
+ : undefined
36
+
37
+ const isMonorepoSubpackage = (exports.isMonorepoSubpackage =
38
+ pnpmWorkspace && Array.isArray(pnpmWorkspace.packages)
39
+ ? pnpmWorkspace.packages.some((p) =>
40
+ new RegExp(`^${p.replace(/\*/g, '[^/]+')}$`).test(
41
+ Path.relative(Path.dirname(pnpmWorkspaceFile), projectDir)
42
+ )
43
+ )
44
+ : false)
45
+
46
+ const isMonorepoRoot = (exports.isMonorepoRoot =
47
+ pnpmWorkspaceFile != null && Path.dirname(pnpmWorkspaceFile) === projectDir)
48
+
49
+ const monorepoProjectDir = (exports.monorepoProjectDir =
50
+ isMonorepoSubpackage || isMonorepoRoot
51
+ ? Path.dirname(pnpmWorkspaceFile)
52
+ : undefined)
53
+
54
+ const monorepoPackageJsonFile = (exports.monorepoPackageJsonFile =
55
+ monorepoProjectDir
56
+ ? Path.join(monorepoProjectDir, 'package.json')
57
+ : undefined)
58
+ exports.monorepoPackageJson = monorepoPackageJsonFile
59
+ ? fs.readJsonSync(monorepoPackageJsonFile)
60
+ : undefined
61
+
62
+ const findGitDir = once(function findGitDir(cwd = process.cwd()) {
63
+ let stopAt = Path.dirname(monorepoProjectDir || projectDir)
64
+ if (stopAt === '/') stopAt = undefined
65
+ return findUp.sync((dir) => (dir === stopAt ? findUp.stop : '.git'), {
66
+ cwd,
67
+ type: 'directory',
68
+ })
69
+ })
70
+ exports.findGitDir = findGitDir
71
+
31
72
  const toolchainPackages = (exports.toolchainPackages = [
73
+ packageJson.name,
32
74
  ...Object.keys(packageJson.dependencies || {}),
33
75
  ...Object.keys(packageJson.devDependencies || {}),
34
76
  ].filter((dep) => dep.startsWith(name)))
35
77
 
36
78
  const toolchainPackageJsons = (exports.toolchainPackageJsons = {})
37
79
  for (const pkg of toolchainPackages) {
38
- toolchainPackageJsons[pkg] = require(require.resolve(`${pkg}/package.json`, {
39
- paths: [projectDir],
40
- }))
80
+ toolchainPackageJsons[pkg] =
81
+ pkg === packageJson.name
82
+ ? packageJson
83
+ : require(require.resolve(`${pkg}/package.json`, {
84
+ paths: [projectDir],
85
+ }))
41
86
  }
42
87
 
43
88
  let toolchainConfigFile
@@ -0,0 +1,6 @@
1
+ module.exports = function isEmpty(obj) {
2
+ if (Array.isArray(obj)) return obj.length === 0
3
+ if (obj instanceof Map || obj instanceof Set) return obj.size === 0
4
+ for (const key in obj) return false
5
+ return true
6
+ }
package/util/isKey.cjs ADDED
@@ -0,0 +1,31 @@
1
+ /** Used to match property names within property paths. */
2
+ const reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/
3
+ const reIsPlainProp = /^\w*$/
4
+
5
+ /**
6
+ * Checks if `value` is a property name and not a property path.
7
+ *
8
+ * @private
9
+ * @param {*} value The value to check.
10
+ * @param {Object} [object] The object to query keys on.
11
+ * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
12
+ */
13
+ module.exports = function isKey(value, object) {
14
+ if (Array.isArray(value)) {
15
+ return false
16
+ }
17
+ const type = typeof value
18
+ if (
19
+ type === 'number' ||
20
+ type === 'boolean' ||
21
+ value == null ||
22
+ typeof value === 'symbol'
23
+ ) {
24
+ return true
25
+ }
26
+ return (
27
+ reIsPlainProp.test(value) ||
28
+ !reIsDeepProp.test(value) ||
29
+ (object != null && value in Object(object))
30
+ )
31
+ }
@@ -0,0 +1,5 @@
1
+ module.exports = function mapValues(obj, iteratee) {
2
+ return Object.fromEntries(
3
+ Object.entries(obj).map(([key, value]) => [key, iteratee(value, key, obj)])
4
+ )
5
+ }
package/util/merge.cjs ADDED
@@ -0,0 +1,15 @@
1
+ module.exports = function merge(a, ...b) {
2
+ return b.reduce((a, b) => {
3
+ if (!(a instanceof Object) || !(b instanceof Object)) return a
4
+ for (const key in b) {
5
+ const aValue = a[key]
6
+ const bValue = b[key]
7
+ if (aValue instanceof Object && bValue instanceof Object) {
8
+ merge(aValue, bValue)
9
+ } else {
10
+ a[key] = bValue
11
+ }
12
+ }
13
+ return a
14
+ }, a)
15
+ }
package/util/pick.cjs ADDED
@@ -0,0 +1,6 @@
1
+ module.exports = function pick(obj, ...keys) {
2
+ const keysSet = new Set(keys.flat())
3
+ return Object.fromEntries(
4
+ Object.entries(obj).filter(([key]) => keysSet.has(key))
5
+ )
6
+ }
@@ -0,0 +1,36 @@
1
+ const charCodeOfDot = '.'.charCodeAt(0)
2
+ const reEscapeChar = /\\(\\)?/g
3
+ const rePropName = RegExp(
4
+ // Match anything that isn't a dot or bracket.
5
+ '[^.[\\]]+' +
6
+ '|' +
7
+ // Or match property names within brackets.
8
+ '\\[(?:' +
9
+ // Match a non-string expression.
10
+ '([^"\'][^[]*)' +
11
+ '|' +
12
+ // Or match strings (supports escaping characters).
13
+ '(["\'])((?:(?!\\2)[^\\\\]|\\\\.)*?)\\2' +
14
+ ')\\]' +
15
+ '|' +
16
+ // Or match "" as the space between consecutive dots or empty brackets.
17
+ '(?=(?:\\.|\\[\\])(?:\\.|\\[\\]|$))',
18
+ 'g'
19
+ )
20
+
21
+ module.exports = function stringToPath(string) {
22
+ const result = []
23
+ if (string.charCodeAt(0) === charCodeOfDot) {
24
+ result.push('')
25
+ }
26
+ string.replace(rePropName, (match, expression, quote, subString) => {
27
+ let key = match
28
+ if (quote) {
29
+ key = subString.replace(reEscapeChar, '$1')
30
+ } else if (expression) {
31
+ key = expression.trim()
32
+ }
33
+ result.push(key)
34
+ })
35
+ return result
36
+ }
package/util/toKey.cjs ADDED
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Converts `value` to a string key if it's not a string or symbol.
3
+ *
4
+ * @private
5
+ * @param {*} value The value to inspect.
6
+ * @returns {string|symbol} Returns the key.
7
+ */
8
+ module.exports = function toKey(value) {
9
+ if (typeof value === 'string' || typeof value === 'symbol') {
10
+ return value
11
+ }
12
+ const result = `${value}`
13
+ return result === '0' && 1 / value === -Infinity ? '-0' : result
14
+ }
package/util/unset.cjs ADDED
@@ -0,0 +1,16 @@
1
+ const castPath = require('./castPath.cjs')
2
+ const toKey = require('./toKey.cjs')
3
+
4
+ /**
5
+ * The base implementation of `unset`.
6
+ *
7
+ * @private
8
+ * @param {Object} object The object to modify.
9
+ * @param {Array|string} path The property path to unset.
10
+ * @returns {boolean} Returns `true` if the property is deleted, else `false`.
11
+ */
12
+ module.exports = function unset(object, path) {
13
+ path = castPath(path, object)
14
+ object = path.slice(0, path.length - 1).reduce((obj, key) => obj[key], object)
15
+ return object == null || delete object[toKey(path[path.length - 1])]
16
+ }
File without changes