@npmcli/template-oss 4.19.0 → 4.20.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.
Files changed (52) hide show
  1. package/README.md +15 -11
  2. package/bin/release-manager.js +6 -0
  3. package/lib/config.js +95 -117
  4. package/lib/content/{_job-matrix.yml → _job-matrix-yml.hbs} +1 -1
  5. package/lib/content/{_job-release-integration.yml → _job-release-integration-yml.hbs} +1 -1
  6. package/lib/content/{_job.yml → _job-yml.hbs} +1 -1
  7. package/lib/content/_step-node-yml.hbs +60 -0
  8. package/lib/content/_steps-setup-yml.hbs +6 -0
  9. package/lib/content/{audit.yml → audit-yml.hbs} +2 -2
  10. package/lib/content/{ci-release.yml → ci-release-yml.hbs} +6 -6
  11. package/lib/content/ci-yml.hbs +13 -0
  12. package/lib/content/{codeql-analysis.yml → codeql-analysis-yml.hbs} +1 -1
  13. package/lib/content/{eslintrc.js → eslintrc-js.hbs} +11 -1
  14. package/lib/content/{gitignore → gitignore.hbs} +2 -0
  15. package/lib/content/index.js +43 -39
  16. package/lib/content/{pkg.json → package-json.hbs} +8 -4
  17. package/lib/content/{post-dependabot.yml → post-dependabot-yml.hbs} +1 -1
  18. package/lib/content/{pull-request.yml → pull-request-yml.hbs} +1 -1
  19. package/lib/content/{release.yml → release-yml.hbs} +10 -10
  20. package/lib/content/tsconfig-json.hbs +17 -0
  21. package/lib/util/files.js +29 -20
  22. package/lib/util/get-cmd-path.js +36 -0
  23. package/lib/util/git.js +6 -2
  24. package/lib/util/import-or-require.js +29 -0
  25. package/lib/util/parser.js +6 -1
  26. package/lib/util/path.js +13 -0
  27. package/lib/util/template.js +9 -6
  28. package/package.json +10 -10
  29. package/lib/content/_step-node.yml +0 -57
  30. package/lib/content/_steps-setup.yml +0 -6
  31. package/lib/content/ci.yml +0 -13
  32. /package/lib/content/{CODEOWNERS → CODEOWNERS.hbs} +0 -0
  33. /package/lib/content/{CODE_OF_CONDUCT.md → CODE_OF_CONDUCT-md.hbs} +0 -0
  34. /package/lib/content/{CONTRIBUTING.md → CONTRIBUTING-md.hbs} +0 -0
  35. /package/lib/content/{LICENSE.md → LICENSE-md.hbs} +0 -0
  36. /package/lib/content/{SECURITY.md → SECURITY-md.hbs} +0 -0
  37. /package/lib/content/{_on-ci.yml → _on-ci-yml.hbs} +0 -0
  38. /package/lib/content/{_step-audit.yml → _step-audit-yml.hbs} +0 -0
  39. /package/lib/content/{_step-checks.yml → _step-checks-yml.hbs} +0 -0
  40. /package/lib/content/{_step-deps.yml → _step-deps-yml.hbs} +0 -0
  41. /package/lib/content/{_step-git.yml → _step-git-yml.hbs} +0 -0
  42. /package/lib/content/{_step-lint.yml → _step-lint-yml.hbs} +0 -0
  43. /package/lib/content/{_step-test.yml → _step-test-yml.hbs} +0 -0
  44. /package/lib/content/{bug.yml → bug-yml.hbs} +0 -0
  45. /package/lib/content/{commitlintrc.js → commitlintrc-js.hbs} +0 -0
  46. /package/lib/content/{config.yml → config-yml.hbs} +0 -0
  47. /package/lib/content/{dependabot.yml → dependabot-yml.hbs} +0 -0
  48. /package/lib/content/{npmrc → npmrc.hbs} +0 -0
  49. /package/lib/content/{release-please-config.json → release-please-config-json.hbs} +0 -0
  50. /package/lib/content/{release-please-manifest.json → release-please-manifest-json.hbs} +0 -0
  51. /package/lib/content/{settings.yml → settings-yml.hbs} +0 -0
  52. /package/lib/content/{tap.json → tap-json.hbs} +0 -0
@@ -5,46 +5,47 @@ const isPublic = (p) => p.config.isPublic
5
5
  const sharedRootAdd = (name) => ({
6
6
  // release
7
7
  '.github/workflows/release.yml': {
8
- file: 'release.yml',
8
+ file: 'release-yml.hbs',
9
9
  filter: isPublic,
10
10
  },
11
11
  '.github/workflows/ci-release.yml': {
12
- file: 'ci-release.yml',
12
+ file: 'ci-release-yml.hbs',
13
13
  filter: isPublic,
14
14
  },
15
15
  '.release-please-manifest.json': {
16
- file: 'release-please-manifest.json',
16
+ file: 'release-please-manifest-json.hbs',
17
17
  filter: isPublic,
18
- parser: (p) => class extends p.JsonMerge {
19
- comment = null
20
- },
18
+ parser: (p) => p.JsonMergeNoComment,
21
19
  },
22
20
  'release-please-config.json': {
23
- file: 'release-please-config.json',
21
+ file: 'release-please-config-json.hbs',
24
22
  filter: isPublic,
25
- parser: (p) => class extends p.JsonMerge {
26
- comment = null
27
- },
23
+ parser: (p) => p.JsonMergeNoComment,
24
+ },
25
+ 'tsconfig.json': {
26
+ file: 'tsconfig-json.hbs',
27
+ filter: (p) => p.config.typescript,
28
+ parser: (p) => p.JsonMergeNoComment,
28
29
  },
29
30
  // this lint commits which is only necessary for releases
30
31
  '.github/workflows/pull-request.yml': {
31
- file: 'pull-request.yml',
32
+ file: 'pull-request-yml.hbs',
32
33
  filter: isPublic,
33
34
  },
34
35
  // ci
35
- '.github/matchers/tap.json': 'tap.json',
36
- [`.github/workflows/ci${name ? `-${name}` : ''}.yml`]: 'ci.yml',
36
+ '.github/matchers/tap.json': 'tap-json.hbs',
37
+ [`.github/workflows/ci${name ? `-${name}` : ''}.yml`]: 'ci-yml.hbs',
37
38
  // dependabot
38
39
  '.github/dependabot.yml': {
39
- file: 'dependabot.yml',
40
+ file: 'dependabot-yml.hbs',
40
41
  filter: (p) => p.config.dependabot,
41
42
  },
42
43
  '.github/workflows/post-dependabot.yml': {
43
- file: 'post-dependabot.yml',
44
+ file: 'post-dependabot-yml.hbs',
44
45
  filter: (p) => p.config.dependabot,
45
46
  },
46
47
  '.github/settings.yml': {
47
- file: 'settings.yml',
48
+ file: 'settings-yml.hbs',
48
49
  filter: (p) => !p.config.isReleaseBranch,
49
50
  },
50
51
  })
@@ -61,15 +62,16 @@ const sharedRootRm = () => ({
61
62
  // Changes applied to the root of the repo
62
63
  const rootRepo = {
63
64
  add: {
64
- '.commitlintrc.js': 'commitlintrc.js',
65
- '.github/ISSUE_TEMPLATE/bug.yml': 'bug.yml',
66
- '.github/ISSUE_TEMPLATE/config.yml': 'config.yml',
67
- '.github/CODEOWNERS': 'CODEOWNERS',
68
- '.github/workflows/audit.yml': 'audit.yml',
69
- '.github/workflows/codeql-analysis.yml': 'codeql-analysis.yml',
65
+ '.commitlintrc.{{ cjsExt }}': 'commitlintrc-js.hbs',
66
+ '.github/ISSUE_TEMPLATE/bug.yml': 'bug-yml.hbs',
67
+ '.github/ISSUE_TEMPLATE/config.yml': 'config-yml.hbs',
68
+ '.github/CODEOWNERS': 'CODEOWNERS.hbs',
69
+ '.github/workflows/audit.yml': 'audit-yml.hbs',
70
+ '.github/workflows/codeql-analysis.yml': 'codeql-analysis-yml.hbs',
70
71
  ...sharedRootAdd(),
71
72
  },
72
73
  rm: {
74
+ '.commitlintrc.{{ deleteJsExt }}': true,
73
75
  '.github/workflows/release-test.yml': true,
74
76
  '.github/workflows/release-please.yml': true,
75
77
  ...sharedRootRm(),
@@ -83,19 +85,19 @@ const rootRepo = {
83
85
  // dir. so we might want to combine these
84
86
  const rootModule = {
85
87
  add: {
86
- '.eslintrc.js': {
87
- file: 'eslintrc.js',
88
+ '.eslintrc.{{ cjsExt }}': {
89
+ file: 'eslintrc-js.hbs',
88
90
  filter: (p) => p.config.eslint,
89
91
  },
90
- '.gitignore': 'gitignore',
91
- '.npmrc': 'npmrc',
92
- 'SECURITY.md': 'SECURITY.md',
93
- 'CODE_OF_CONDUCT.md': 'CODE_OF_CONDUCT.md',
94
- 'CONTRIBUTING.md': 'CONTRIBUTING.md',
95
- 'package.json': 'pkg.json',
92
+ '.gitignore': 'gitignore.hbs',
93
+ '.npmrc': 'npmrc.hbs',
94
+ 'SECURITY.md': 'SECURITY-md.hbs',
95
+ 'CODE_OF_CONDUCT.md': 'CODE_OF_CONDUCT-md.hbs',
96
+ 'CONTRIBUTING.md': 'CONTRIBUTING-md.hbs',
97
+ 'package.json': 'package-json.hbs',
96
98
  },
97
99
  rm: [
98
- '.eslintrc.!(js|local.*)',
100
+ '.eslintrc.!({{ cjsExt }}|local.*)',
99
101
  ],
100
102
  }
101
103
 
@@ -114,16 +116,16 @@ const workspaceRepo = {
114
116
  // Changes for each workspace but applied to the relative workspace dir
115
117
  const workspaceModule = {
116
118
  add: {
117
- '.eslintrc.js': {
118
- file: 'eslintrc.js',
119
+ '.eslintrc.{{ cjsExt }}': {
120
+ file: 'eslintrc-js.hbs',
119
121
  filter: (p) => p.config.eslint,
120
122
  },
121
- '.gitignore': 'gitignore',
122
- 'package.json': 'pkg.json',
123
+ '.gitignore': 'gitignore.hbs',
124
+ 'package.json': 'package-json.hbs',
123
125
  },
124
126
  rm: [
125
127
  '.npmrc',
126
- '.eslintrc.!(js|local.*)',
128
+ '.eslintrc.!({{ cjsExt }}|local.*)',
127
129
  'SECURITY.md',
128
130
  ],
129
131
  }
@@ -144,8 +146,6 @@ module.exports = {
144
146
  'lib/',
145
147
  ],
146
148
  allowPaths: [
147
- '/bin/',
148
- '/lib/',
149
149
  '/.eslintrc.local.*',
150
150
  '**/.gitignore',
151
151
  '/docs/',
@@ -157,13 +157,17 @@ module.exports = {
157
157
  '/LICENSE*',
158
158
  '/CHANGELOG*',
159
159
  ],
160
- ignorePaths: [],
160
+ ignorePaths: [
161
+ /* to be provided by consuming package */
162
+ ],
161
163
  ciVersions: {},
162
164
  latestCiVersion: 20,
163
165
  lockfile: false,
164
166
  codeowner: '@npm/cli-team',
165
167
  eslint: true,
166
168
  publish: false,
169
+ typescript: false,
170
+ esm: false,
167
171
  updateNpm: true,
168
172
  dependabot: 'increase-if-necessary',
169
173
  unwantedPackages: [
@@ -1,8 +1,9 @@
1
1
  {
2
2
  "author": "GitHub Inc.",
3
- "files": {{{ json distPaths }}},
3
+ "files": {{#if typescript}}{{{ del }}}{{else}}{{{ json distPaths }}}{{/if}},
4
+ "type": {{#if esm}}"module"{{else}}{{{ del }}}{{/if}},
4
5
  "scripts": {
5
- "lint": "{{#if eslint}}eslint \"**/*.js\"{{else}}echo linting disabled{{/if}}",
6
+ "lint": "{{#if eslint}}eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"{{else}}echo linting disabled{{/if}}",
6
7
  "postlint": "template-oss-check",
7
8
  "template-oss-apply": "template-oss-apply --force",
8
9
  "lintfix": "{{ localNpmPath }} run lint -- --fix",
@@ -13,6 +14,9 @@
13
14
  "test-all": "{{ localNpmPath }} run test {{ allFlags }}",
14
15
  "lint-all": "{{ localNpmPath }} run lint {{ allFlags }}",
15
16
  {{/if}}
17
+ {{#if typescript}}
18
+ "prepare": "tshy",
19
+ {{/if}}
16
20
  "template-copy": {{{ del }}},
17
21
  "lint:fix": {{{ del }}},
18
22
  "preversion": {{{ del }}},
@@ -30,13 +34,13 @@
30
34
  {{#if workspacePaths}}
31
35
  "test-ignore": "^({{ join workspacePaths "|" }})/",
32
36
  {{/if}}
33
- "nyc-arg": [
37
+ "nyc-arg": {{#if tap18}}{{{ del }}}{{else}}[
34
38
  {{#each workspaceGlobs}}
35
39
  "--exclude",
36
40
  "{{ . }}",
37
41
  {{/each}}
38
42
  "--exclude",
39
43
  "tap-snapshots/**"
40
- ]
44
+ ]{{/if}}
41
45
  }
42
46
  }
@@ -8,7 +8,7 @@ permissions:
8
8
 
9
9
  jobs:
10
10
  template-oss:
11
- {{> job
11
+ {{> jobYml
12
12
  jobName="template-oss"
13
13
  jobIf="github.actor == 'dependabot[bot]'"
14
14
  jobCheckout=(obj ref="${{ github.event.pull_request.head.ref }}")
@@ -10,7 +10,7 @@ on:
10
10
 
11
11
  jobs:
12
12
  commitlint:
13
- {{> job jobName="Lint Commits" jobCheckout=(obj fetch-depth=0) }}
13
+ {{> jobYml jobName="Lint Commits" jobCheckout=(obj fetch-depth=0) }}
14
14
  - name: Run Commitlint on Commits
15
15
  id: commit
16
16
  continue-on-error: true
@@ -27,7 +27,7 @@ jobs:
27
27
  pr-number: $\{{ steps.release.outputs.pr-number }}
28
28
  comment-id: $\{{ steps.pr-comment.outputs.result }}
29
29
  check-id: $\{{ steps.check.outputs.check_id }}
30
- {{> job jobName="Release" }}
30
+ {{> jobYml jobName="Release" }}
31
31
  - name: Release Please
32
32
  id: release
33
33
  env:
@@ -66,14 +66,14 @@ jobs:
66
66
  }
67
67
 
68
68
  return commentId
69
- {{> stepChecks jobCheck=(obj name="Release" sha="steps.release.outputs.pr-sha") }}
69
+ {{> stepChecksYml jobCheck=(obj name="Release" sha="steps.release.outputs.pr-sha") }}
70
70
 
71
71
  update:
72
72
  needs: release
73
73
  outputs:
74
74
  sha: $\{{ steps.commit.outputs.sha }}
75
75
  check-id: $\{{ steps.check.outputs.check_id }}
76
- {{> job
76
+ {{> jobYml
77
77
  jobName="Update - Release"
78
78
  jobIf="needs.release.outputs.pr"
79
79
  jobCheckout=(obj ref="${{ needs.release.outputs.branch }}" fetch-depth=0)
@@ -94,8 +94,8 @@ jobs:
94
94
  git commit --all --amend --no-edit || true
95
95
  git push --force-with-lease
96
96
  echo "sha=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
97
- {{> stepChecks jobName="Update - Release" jobCheck=(obj sha="steps.commit.outputs.sha" name="Release" )}}
98
- {{> stepChecks jobCheck=(obj id="needs.release.outputs.check-id" )}}
97
+ {{> stepChecksYml jobName="Update - Release" jobCheck=(obj sha="steps.commit.outputs.sha" name="Release" )}}
98
+ {{> stepChecksYml jobCheck=(obj id="needs.release.outputs.check-id" )}}
99
99
 
100
100
  ci:
101
101
  name: CI - Release
@@ -108,7 +108,7 @@ jobs:
108
108
 
109
109
  post-ci:
110
110
  needs: [release, update, ci]
111
- {{> job jobName="Post CI - Release" jobIf="needs.release.outputs.pr && always()" jobSkipSetup=true }}
111
+ {{> jobYml jobName="Post CI - Release" jobIf="needs.release.outputs.pr && always()" jobSkipSetup=true }}
112
112
  - name: Get Needs Result
113
113
  id: needs-result
114
114
  run: |
@@ -121,11 +121,11 @@ jobs:
121
121
  result="success"
122
122
  fi
123
123
  echo "result=$result" >> $GITHUB_OUTPUT
124
- {{> stepChecks jobCheck=(obj id="needs.update.outputs.check-id" status="steps.needs-result.outputs.result") }}
124
+ {{> stepChecksYml jobCheck=(obj id="needs.update.outputs.check-id" status="steps.needs-result.outputs.result") }}
125
125
 
126
126
  post-release:
127
127
  needs: release
128
- {{> job jobName="Post Release - Release" jobIf="needs.release.outputs.releases" jobSkipSetup=true }}
128
+ {{> jobYml jobName="Post Release - Release" jobIf="needs.release.outputs.releases" jobSkipSetup=true }}
129
129
  - name: Create Release PR Comment
130
130
  uses: actions/github-script@v6
131
131
  env:
@@ -163,11 +163,11 @@ jobs:
163
163
  needs: release
164
164
  name: Release Integration
165
165
  if: needs.release.outputs.release
166
- {{> jobReleaseIntegration }}
166
+ {{> jobReleaseIntegrationYml }}
167
167
 
168
168
  post-release-integration:
169
169
  needs: [release, release-integration]
170
- {{> job jobName="Post Release Integration - Release" jobIf="needs.release.outputs.release && always()" jobSkipSetup=true }}
170
+ {{> jobYml jobName="Post Release Integration - Release" jobIf="needs.release.outputs.release && always()" jobSkipSetup=true }}
171
171
  - name: Get Needs Result
172
172
  id: needs-result
173
173
  run: |
@@ -0,0 +1,17 @@
1
+ {
2
+ "compilerOptions": {
3
+ "jsx": "react",
4
+ "declaration": true,
5
+ "declarationMap": true,
6
+ "inlineSources": true,
7
+ "esModuleInterop": true,
8
+ "forceConsistentCasingInFileNames": true,
9
+ "moduleResolution": "nodenext",
10
+ "resolveJsonModule": true,
11
+ "skipLibCheck": true,
12
+ "sourceMap": true,
13
+ "strict": true,
14
+ "target": "es2022",
15
+ "module": "nodenext"
16
+ }
17
+ }
package/lib/util/files.js CHANGED
@@ -1,5 +1,5 @@
1
1
  const { join } = require('path')
2
- const { defaultsDeep, omit } = require('lodash')
2
+ const { defaultsDeep, omit, isPlainObject } = require('lodash')
3
3
  const deepMapValues = require('just-deep-map-values')
4
4
  const { glob } = require('glob')
5
5
  const { mergeWithCustomizers, customizers } = require('./merge.js')
@@ -12,6 +12,11 @@ const FILE_KEYS = ['rootRepo', 'rootModule', 'workspaceRepo', 'workspaceModule']
12
12
 
13
13
  const globify = pattern => pattern.split('\\').join('/')
14
14
 
15
+ const deepMapKeys = (obj, fn) => Object.entries(obj).reduce((acc, [key, value]) => {
16
+ acc[fn(key)] = isPlainObject(value) ? deepMapKeys(value, fn) : value
17
+ return acc
18
+ }, {})
19
+
15
20
  const mergeFiles = mergeWithCustomizers((value, srcValue, key, target, source, stack) => {
16
21
  // This will merge all files except if the src file has overwrite:false. Then
17
22
  // the files will be turned into an array so they can be applied on top of
@@ -35,7 +40,7 @@ const fileEntries = (dir, files, options, { allowMultipleSources = true } = {})
35
40
  continue
36
41
  }
37
42
 
38
- // target paths need to be joinsed with dir and templated
43
+ // target paths need to be joined with dir and templated
39
44
  const target = join(dir, template(key, options))
40
45
 
41
46
  if (Array.isArray(source)) {
@@ -66,7 +71,7 @@ const getParsers = (dir, files, options, parseOptions) => {
66
71
  const clean = typeof shouldClean === 'function' ? shouldClean(options) : false
67
72
 
68
73
  if (parser) {
69
- // allow files to extend base parsers or create new ones
74
+ // allow files to extend base parsers or create new ones
70
75
  return new (parser(Parser.Parsers))(target, file, options, { clean })
71
76
  }
72
77
 
@@ -105,23 +110,27 @@ const parseEach = async (dir, files, options, parseOptions, fn) => {
105
110
  return res.filter(Boolean)
106
111
  }
107
112
 
108
- const parseConfig = (files, dir, overrides) => {
109
- const normalizeFiles = (v) => deepMapValues(v, (value, key) => {
110
- if (key === RM_KEY && Array.isArray(value)) {
111
- return value.reduce((acc, k) => {
112
- acc[k] = true
113
- return acc
114
- }, {})
115
- }
116
- if (typeof value === 'string') {
117
- const file = join(dir, value)
118
- return key === 'file' ? file : { file }
119
- }
120
- if (value === true && FILE_KEYS.includes(key)) {
121
- return {}
122
- }
123
- return value
124
- })
113
+ const parseConfig = (files, dir, overrides, templateSettings) => {
114
+ const normalizeFiles = (v) => {
115
+ v = deepMapKeys(v, (s) => template(s, templateSettings))
116
+ return deepMapValues(v, (value, key) => {
117
+ if (key === RM_KEY && Array.isArray(value)) {
118
+ return value.reduce((acc, k) => {
119
+ // template files nows since they need to be normalized before merging
120
+ acc[template(k, templateSettings)] = true
121
+ return acc
122
+ }, {})
123
+ }
124
+ if (typeof value === 'string') {
125
+ const file = join(dir, value)
126
+ return key === 'file' ? file : { file }
127
+ }
128
+ if (value === true && FILE_KEYS.includes(key)) {
129
+ return {}
130
+ }
131
+ return value
132
+ })
133
+ }
125
134
 
126
135
  const merged = mergeFiles(normalizeFiles(files), normalizeFiles(overrides))
127
136
  const withDefaults = defaultsDeep(merged, FILE_KEYS.reduce((acc, k) => {
@@ -0,0 +1,36 @@
1
+ const { join, relative } = require('path')
2
+ const { makePosix } = require('./path.js')
3
+
4
+ const getCmdPath = (key, { pkgConfig, rootConfig, isRoot, pkg, rootPkg }) => {
5
+ const result = (local, isRelative) => {
6
+ let root = local
7
+ const isLocal = local.startsWith('.') || local.startsWith('/')
8
+
9
+ if (isLocal) {
10
+ if (isRelative) {
11
+ // Make a path relative from a workspace to the root if we are in a workspace
12
+ local = makePosix(join(relative(pkg.path, rootPkg.path), local))
13
+ }
14
+ local = `node ${local}`
15
+ root = `node ${root}`
16
+ }
17
+
18
+ return {
19
+ isLocal,
20
+ local,
21
+ root,
22
+ }
23
+ }
24
+
25
+ if (pkgConfig[key]) {
26
+ return result(pkgConfig[key])
27
+ }
28
+
29
+ if (rootConfig[key]) {
30
+ return result(rootConfig[key], !isRoot)
31
+ }
32
+
33
+ return result(key)
34
+ }
35
+
36
+ module.exports = getCmdPath
package/lib/util/git.js CHANGED
@@ -19,9 +19,9 @@ const tryGit = async (path, ...args) => {
19
19
 
20
20
  // parse a repo from a git origin into a format
21
21
  // for a package.json#repository object
22
- const getUrl = async (path) => {
22
+ const getRemoteUrl = async (path, remote) => {
23
23
  try {
24
- const urlStr = await tryGit(path, 'remote', 'get-url', 'origin')
24
+ const urlStr = await tryGit(path, 'remote', 'get-url', remote)
25
25
  const { domain, user, project } = hgi.fromUrl(urlStr)
26
26
  const url = new URL(`https://${domain}`)
27
27
  url.pathname = `/${user}/${project}.git`
@@ -31,6 +31,10 @@ const getUrl = async (path) => {
31
31
  }
32
32
  }
33
33
 
34
+ const getUrl = async (path) => {
35
+ return (await getRemoteUrl(path, 'upstream')) ?? (await getRemoteUrl(path, 'origin'))
36
+ }
37
+
34
38
  const getBranches = async (path, branchPatterns) => {
35
39
  let matchingBranches = new Set()
36
40
  let matchingPatterns = new Set()
@@ -0,0 +1,29 @@
1
+ // This fixes weird behavior I was seeing where calls to require(path) would
2
+ // fail the first time and then fetch via dynamic import which is correct, but
3
+ // then subsequent requires for the same path would return an empty object. Not
4
+ // sure if a bug or I'm doing something wrong but since the require/imports here
5
+ // are short lived, it is safe to create our own cache and use that.
6
+ const { pathToFileURL } = require('url')
7
+
8
+ const importOrRequireCache = new Map()
9
+
10
+ const importOrRequire = async (path) => {
11
+ if (importOrRequireCache.has(path)) {
12
+ return importOrRequireCache.get(path)
13
+ }
14
+ let content = {}
15
+ try {
16
+ content = require(path)
17
+ } catch {
18
+ try {
19
+ content = await import(pathToFileURL(path)).then(r => r.default)
20
+ } catch {
21
+ // its ok if this fails since the content dir might only be to provide
22
+ // other files. the index.js is optional
23
+ }
24
+ }
25
+ importOrRequireCache.set(path, content)
26
+ return content
27
+ }
28
+
29
+ module.exports = importOrRequire
@@ -173,7 +173,7 @@ class Gitignore extends Base {
173
173
  }
174
174
 
175
175
  class Js extends Base {
176
- static types = ['*.js']
176
+ static types = ['*.js', '*.cjs']
177
177
  comment = (c) => `/* ${c} */`
178
178
  }
179
179
 
@@ -306,6 +306,10 @@ class JsonMerge extends Json {
306
306
  merge = (t, s) => merge(t, s)
307
307
  }
308
308
 
309
+ class JsonMergeNoComment extends JsonMerge {
310
+ comment = null
311
+ }
312
+
309
313
  class PackageJson extends JsonMerge {
310
314
  static types = ['package.json']
311
315
 
@@ -346,6 +350,7 @@ const Parsers = {
346
350
  YmlMerge,
347
351
  Json,
348
352
  JsonMerge,
353
+ JsonMergeNoComment,
349
354
  PackageJson,
350
355
  }
351
356
 
@@ -0,0 +1,13 @@
1
+ const { posix, win32 } = require('path')
2
+
3
+ const makePosix = (v) => v.split(win32.sep).join(posix.sep)
4
+ const deglob = (v) => makePosix(v).replace(/[/*]+$/, '')
5
+ const posixDir = (v) => `${v === '.' ? '' : deglob(v).replace(/\/$/, '')}${posix.sep}`
6
+ const posixGlob = (str) => `${posixDir(str)}**`
7
+
8
+ module.exports = {
9
+ makePosix,
10
+ deglob,
11
+ posixDir,
12
+ posixGlob,
13
+ }
@@ -31,7 +31,7 @@ const makePartials = (dir, isBase) => {
31
31
  Handlebars.registerPartial(partials)
32
32
  }
33
33
 
34
- const setupHandlebars = (baseDir, ...otherDirs) => {
34
+ const setupHandlebars = (dirs) => {
35
35
  Handlebars.registerHelper('obj', ({ hash }) => Object.fromEntries(safeValues(hash)))
36
36
  Handlebars.registerHelper('join', (arr, sep) => arr.join(typeof sep === 'string' ? sep : ', '))
37
37
  Handlebars.registerHelper('pluck', (arr, key) => arr.map(a => a[key]))
@@ -40,14 +40,17 @@ const setupHandlebars = (baseDir, ...otherDirs) => {
40
40
  Handlebars.registerHelper('json', (c) => JSON.stringify(c))
41
41
  Handlebars.registerHelper('del', () => JSON.stringify(DELETE))
42
42
 
43
- makePartials(baseDir, true)
44
- for (const dir of otherDirs) {
45
- makePartials(dir)
43
+ if (Array.isArray(dirs)) {
44
+ const [baseDir, ...otherDirs] = dirs
45
+ makePartials(baseDir, true)
46
+ for (const dir of otherDirs) {
47
+ makePartials(dir)
48
+ }
46
49
  }
47
50
  }
48
51
 
49
- const template = (str, { config, ...options }) => {
50
- setupHandlebars(...config.__PARTIAL_DIRS__)
52
+ const template = (str, { config = {}, ...options }) => {
53
+ setupHandlebars(config.__PARTIAL_DIRS__)
51
54
 
52
55
  const t = Handlebars.compile(str, { strict: true })
53
56
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@npmcli/template-oss",
3
- "version": "4.19.0",
3
+ "version": "4.20.0",
4
4
  "description": "templated files used in npm CLI team oss projects",
5
5
  "main": "lib/content/index.js",
6
6
  "bin": {
@@ -10,7 +10,7 @@
10
10
  "template-oss-release-manager": "bin/release-manager.js"
11
11
  },
12
12
  "scripts": {
13
- "lint": "eslint \"**/*.js\"",
13
+ "lint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"",
14
14
  "lintfix": "npm run lint -- --fix",
15
15
  "posttest": "npm run lint",
16
16
  "snap": "tap",
@@ -33,25 +33,25 @@
33
33
  "license": "ISC",
34
34
  "dependencies": {
35
35
  "@actions/core": "^1.9.1",
36
- "@commitlint/cli": "^17.1.1",
37
- "@commitlint/config-conventional": "^17.1.0",
36
+ "@commitlint/cli": "^18.2.0",
37
+ "@commitlint/config-conventional": "^18.1.0",
38
38
  "@isaacs/string-locale-compare": "^1.1.0",
39
- "@npmcli/arborist": "^6.0.0",
40
- "@npmcli/git": "^4.0.0",
39
+ "@npmcli/arborist": "^7.2.1",
40
+ "@npmcli/git": "^5.0.3",
41
41
  "@npmcli/map-workspaces": "^3.0.0",
42
- "@npmcli/package-json": "^4.0.0",
42
+ "@npmcli/package-json": "^5.0.0",
43
43
  "@octokit/rest": "^19.0.4",
44
44
  "diff": "^5.0.0",
45
45
  "glob": "^10.1.0",
46
46
  "handlebars": "^4.7.7",
47
- "hosted-git-info": "^6.0.0",
47
+ "hosted-git-info": "^7.0.1",
48
48
  "ini": "^4.0.0",
49
49
  "json-parse-even-better-errors": "^3.0.0",
50
50
  "just-deep-map-values": "^1.1.1",
51
51
  "just-diff": "^6.0.0",
52
52
  "lodash": "^4.17.21",
53
53
  "minimatch": "^9.0.2",
54
- "npm-package-arg": "^10.0.0",
54
+ "npm-package-arg": "^11.0.1",
55
55
  "proc-log": "^3.0.0",
56
56
  "release-please": "npm:@npmcli/release-please@^14.2.6",
57
57
  "semver": "^7.3.5",
@@ -81,7 +81,7 @@
81
81
  "publish": true
82
82
  },
83
83
  "engines": {
84
- "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
84
+ "node": "^18.17.0 || >=20.5.0"
85
85
  },
86
86
  "workspaces": [
87
87
  "workspace/test-workspace"