@npmcli/template-oss 1.0.0 → 2.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/LICENSE.md CHANGED
@@ -1,3 +1,5 @@
1
+ <!-- This file is automatically added by @npmcli/template-oss. Do not edit. -->
2
+
1
3
  ISC License
2
4
 
3
5
  Copyright npm, Inc.
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env node
2
+
3
+ const check = require('../lib/check.js')
4
+
5
+ const main = async () => {
6
+ const {
7
+ npm_config_local_prefix: root,
8
+ } = process.env
9
+
10
+ if (!root) {
11
+ throw new Error('This package requires npm >7.21.1')
12
+ }
13
+
14
+ const problems = await check(root)
15
+ if (problems.length) {
16
+ console.error('Some problems were detected:')
17
+ console.error()
18
+ console.error(problems.map((problem) => problem.message).join('\n'))
19
+ console.error()
20
+ console.error('To correct them:')
21
+ console.error(problems.map((problem) => problem.solution).join('\n'))
22
+ process.exitCode = 1
23
+ }
24
+ }
25
+
26
+ module.exports = main().catch((err) => {
27
+ console.error(err.stack)
28
+ process.exitCode = 1
29
+ })
@@ -1,28 +1,30 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- const { dirname } = require('path')
4
-
5
3
  const copyContent = require('../lib/content/index.js')
6
- const installPackages = require('../lib/install.js')
7
4
  const patchPackage = require('../lib/package.js')
8
5
 
9
6
  const main = async () => {
10
- const pkgPath = process.env.npm_package_json
11
- if (!pkgPath) {
12
- throw new Error('This script must be run as an npm lifecycle event')
13
- }
7
+ const {
8
+ npm_config_global: globalMode,
9
+ npm_config_local_prefix: root,
10
+ } = process.env
14
11
 
15
- const root = dirname(pkgPath)
12
+ // do nothing in global mode or when the local prefix isn't set
13
+ if (globalMode === 'true' || !root) {
14
+ return
15
+ }
16
16
 
17
17
  const needsAction = await patchPackage(root)
18
- if (needsAction) {
19
- await copyContent(root)
20
- return installPackages(root)
18
+ if (!needsAction) {
19
+ return
21
20
  }
21
+
22
+ return copyContent(root)
22
23
  }
23
24
 
24
- // we export the promise so it can be awaited in tests
25
- module.exports = main().catch((err) => {
25
+ // we export the promise so it can be awaited in tests, coverage is disabled
26
+ // for the catch handler because it does so little it's not worth testing
27
+ module.exports = main().catch(/* istanbul ignore next */ (err) => {
26
28
  console.error(err.stack)
27
29
  process.exitCode = 1
28
30
  })
package/lib/check.js ADDED
@@ -0,0 +1,95 @@
1
+ const { join } = require('path')
2
+ const fs = require('@npmcli/fs')
3
+
4
+ const patchPackage = require('./package.js')
5
+
6
+ const unwantedPackages = [
7
+ '@npmcli/lint',
8
+ 'eslint-plugin-promise',
9
+ 'eslint-plugin-standard',
10
+ 'eslint-plugin-import',
11
+ ]
12
+
13
+ const hasOwn = (obj, key) => Object.prototype.hasOwnProperty.call(obj, key)
14
+
15
+ const check = async (root) => {
16
+ const pkgPath = join(root, 'package.json')
17
+ try {
18
+ var contents = await fs.readFile(pkgPath, { encoding: 'utf8' })
19
+ } catch (err) {
20
+ throw new Error('No package.json found')
21
+ }
22
+
23
+ const pkg = JSON.parse(contents)
24
+
25
+ const problems = []
26
+
27
+ const incorrectFields = []
28
+ // 1. ensure package.json changes have been applied
29
+ for (const [key, value] of Object.entries(patchPackage.changes)) {
30
+ if (!hasOwn(pkg, key)) {
31
+ incorrectFields.push({
32
+ name: key,
33
+ found: pkg[key],
34
+ expected: value,
35
+ })
36
+ continue
37
+ }
38
+
39
+ if (value && typeof value === 'object') {
40
+ for (const [subKey, subValue] of Object.entries(value)) {
41
+ if (!hasOwn(pkg[key], subKey) ||
42
+ pkg[key][subKey] !== subValue) {
43
+ incorrectFields.push({
44
+ name: `${key}.${subKey}`,
45
+ found: pkg[key][subKey],
46
+ expected: subValue,
47
+ })
48
+ }
49
+ }
50
+ } else {
51
+ if (pkg[key] !== patchPackage.changes[key]) {
52
+ incorrectFields.push({
53
+ name: key,
54
+ found: pkg[key],
55
+ expected: value,
56
+ })
57
+ }
58
+ }
59
+ }
60
+
61
+ if (incorrectFields.length) {
62
+ problems.push({
63
+ message: [
64
+ `The following package.json fields are incorrect:`,
65
+ ...incorrectFields.map((field) => {
66
+ const { name, found, expected } = field
67
+ return ` Field: "${name}" Expected: "${expected}" Found: "${found}"`
68
+ }),
69
+ ].join('\n'),
70
+ solution: 'npm rm @npmcli/template-oss && npm i -D @npmcli/template-oss',
71
+ })
72
+ }
73
+
74
+ // 2. ensure packages that should not be present are removed
75
+ const mustRemove = unwantedPackages.filter((name) => {
76
+ return hasOwn(pkg.dependencies || {}, name) ||
77
+ hasOwn(pkg.devDependencies || {}, name)
78
+ })
79
+
80
+ if (mustRemove.length) {
81
+ problems.push({
82
+ message: [
83
+ 'The following unwanted packages were found:',
84
+ ...mustRemove,
85
+ ].join(' '),
86
+ solution: `npm rm ${mustRemove.join(' ')}`,
87
+ })
88
+ }
89
+
90
+ return problems
91
+ }
92
+
93
+ check.unwantedPackages = unwantedPackages
94
+
95
+ module.exports = check
@@ -1,3 +1,5 @@
1
+ <!-- This file is automatically added by @npmcli/template-oss. Do not edit. -->
2
+
1
3
  ISC License
2
4
 
3
5
  Copyright npm, Inc.
@@ -0,0 +1 @@
1
+ Please send vulnerability reports through [hackerone](https://hackerone.com/github).
@@ -0,0 +1,54 @@
1
+ # This file is automatically added by @npmcli/template-oss. Do not edit.
2
+
3
+ name: Bug
4
+ description: File a bug/issue
5
+ title: "[BUG] <title>"
6
+ labels: [Bug, Needs Triage]
7
+ body:
8
+ - type: checkboxes
9
+ attributes:
10
+ label: Is there an existing issue for this?
11
+ description: Please [search here](./issues) to see if an issue already exists for your problem.
12
+ options:
13
+ - label: I have searched the existing issues
14
+ required: true
15
+ - type: textarea
16
+ attributes:
17
+ label: Current Behavior
18
+ description: A clear & concise description of what you're experiencing.
19
+ validations:
20
+ required: false
21
+ - type: textarea
22
+ attributes:
23
+ label: Expected Behavior
24
+ description: A clear & concise description of what you expected to happen.
25
+ validations:
26
+ required: false
27
+ - type: textarea
28
+ attributes:
29
+ label: Steps To Reproduce
30
+ description: Steps to reproduce the behavior.
31
+ value: |
32
+ 1. In this environment...
33
+ 2. With this config...
34
+ 3. Run '...'
35
+ 4. See error...
36
+ validations:
37
+ required: false
38
+ - type: textarea
39
+ attributes:
40
+ label: Environment
41
+ description: |
42
+ examples:
43
+ - **npm**: 7.6.3
44
+ - **Node**: 13.14.0
45
+ - **OS**: Ubuntu 20.04
46
+ - **platform**: Macbook Pro
47
+ value: |
48
+ - npm:
49
+ - Node:
50
+ - OS:
51
+ - platform:
52
+ validations:
53
+ required: false
54
+
@@ -1,3 +1,5 @@
1
+ # This file is automatically added by @npmcli/template-oss. Do not edit.
2
+
1
3
  name: CI
2
4
 
3
5
  on:
@@ -24,7 +26,7 @@ jobs:
24
26
  strategy:
25
27
  fail-fast: false
26
28
  matrix:
27
- node-version: [10.0.x, 10.x, 12.0.x, 12.x, 14.0.x, 14.x, 15.x, 16.x]
29
+ node-version: [12.13.0, 12.x, 14.15.0, 14.x, 16.x]
28
30
  platform:
29
31
  - os: ubuntu-latest
30
32
  shell: bash
@@ -0,0 +1,3 @@
1
+ # This file is automatically added by @npmcli/template-oss. Do not edit.
2
+
3
+ blank_issues_enabled: true
@@ -1,3 +1,5 @@
1
+ // This file is automatically added by @npmcli/template-oss. Do not edit.
2
+
1
3
  const { readdirSync: readdir } = require('fs')
2
4
 
3
5
  const localConfigs = readdir(__dirname)
@@ -1,3 +1,5 @@
1
+ # This file is automatically added by @npmcli/template-oss. Do not edit.
2
+
1
3
  # ignore everything in the root
2
4
  /*
3
5
 
@@ -6,8 +6,11 @@ const fs = require('@npmcli/fs')
6
6
  const content = {
7
7
  '.eslintrc.js': './eslintrc.js',
8
8
  '.github/workflows/ci.yml': './ci.yml',
9
+ '.github/ISSUE_TEMPLATE/bug.yml': './bug.yml',
10
+ '.github/ISSUE_TEMPLATE/config.yml': './config.yml',
9
11
  '.gitignore': './gitignore',
10
12
  'LICENSE.md': './LICENSE.md',
13
+ 'SECURITY.md': './SECURITY.md',
11
14
  }
12
15
 
13
16
  // given a root directory, copy all files in the content map
package/lib/package.js CHANGED
@@ -9,6 +9,7 @@ const changes = {
9
9
  templateVersion: TEMPLATE_VERSION,
10
10
  scripts: {
11
11
  lint: `eslint '**/*.js'`,
12
+ postlint: 'npm-template-check',
12
13
  lintfix: 'npm run lint -- --fix',
13
14
  preversion: 'npm test',
14
15
  postversion: 'npm publish',
@@ -17,6 +18,9 @@ const changes = {
17
18
  test: 'tap',
18
19
  posttest: 'npm run lint',
19
20
  },
21
+ engines: {
22
+ node: '^12.13.0 || ^14.15.0 || >=16',
23
+ },
20
24
  }
21
25
 
22
26
  const patchPackage = async (root) => {
package/package.json CHANGED
@@ -1,18 +1,23 @@
1
1
  {
2
2
  "name": "@npmcli/template-oss",
3
- "version": "1.0.0",
3
+ "version": "2.0.0",
4
4
  "description": "templated files used in npm CLI team oss projects",
5
5
  "main": "lib/index.js",
6
+ "bin": {
7
+ "npm-template-check": "bin/npm-template-check.js"
8
+ },
6
9
  "scripts": {
7
10
  "lint": "eslint '**/*.js'",
8
11
  "lintfix": "npm run lint -- --fix",
9
- "preversion": "npm test",
12
+ "postinstall": "node bin/postinstall.js",
13
+ "postlint": "npm-template-check",
14
+ "posttest": "npm run lint",
10
15
  "postversion": "npm publish",
16
+ "prelint": "ln -sf ../../bin/npm-template-check.js node_modules/.bin/npm-template-check",
11
17
  "prepublishOnly": "git push origin --follow-tags",
18
+ "preversion": "npm test",
12
19
  "snap": "tap",
13
- "test": "tap",
14
- "posttest": "npm run lint",
15
- "postinstall": "node bin/postinstall.js"
20
+ "test": "tap"
16
21
  },
17
22
  "repository": {
18
23
  "type": "git",
@@ -34,11 +39,17 @@
34
39
  "lib"
35
40
  ],
36
41
  "devDependencies": {
37
- "@npmcli/eslint-config": "^1.0.0",
42
+ "@npmcli/eslint-config": "*",
38
43
  "eslint": "^7.32.0",
39
44
  "eslint-plugin-node": "^11.1.0",
40
- "spawk": "^1.7.1",
45
+ "tap": "*"
46
+ },
47
+ "peerDependencies": {
48
+ "@npmcli/eslint-config": "^1.0.0",
41
49
  "tap": "^15.0.9"
42
50
  },
43
- "templateVersion": "1.0.0"
51
+ "templateVersion": "1.0.3",
52
+ "engines": {
53
+ "node": "^12.13.0 || ^14.15.0 || >=16"
54
+ }
44
55
  }
package/lib/install.js DELETED
@@ -1,31 +0,0 @@
1
- const spawn = require('@npmcli/promise-spawn')
2
-
3
- const removeDeps = [
4
- 'eslint-plugin-import',
5
- 'eslint-plugin-promise',
6
- 'eslint-plugin-standard',
7
- '@npmcli/lint',
8
- ]
9
-
10
- const devDeps = [
11
- 'eslint',
12
- 'eslint-plugin-node',
13
- '@npmcli/eslint-config',
14
- 'tap',
15
- ]
16
-
17
- const npm = (root, args) => {
18
- return spawn('npm', args, {
19
- cwd: root,
20
- stdioString: true,
21
- })
22
- }
23
-
24
- const installPackages = async (root) => {
25
- await npm(root, ['uninstall', ...removeDeps])
26
- return npm(root, ['install', '--save-dev', ...devDeps])
27
- }
28
- installPackages.removeDeps = removeDeps
29
- installPackages.devDeps = devDeps
30
-
31
- module.exports = installPackages