npm-update-package 0.31.2 → 0.31.3

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 (178) hide show
  1. package/.eslintignore +3 -0
  2. package/.eslintrc.js +23 -0
  3. package/.github/renovate.json +15 -0
  4. package/.github/workflows/eslint.yml +14 -0
  5. package/.github/workflows/test.yml +20 -0
  6. package/.husky/pre-commit +4 -0
  7. package/.nvmrc +1 -0
  8. package/dist/package.json +1 -4
  9. package/dist/src/bin.js +24 -0
  10. package/dist/src/core/FailedResult.js +2 -0
  11. package/dist/src/core/OutdatedPackage.js +2 -0
  12. package/dist/src/core/OutdatedPackageProcessor.js +79 -0
  13. package/dist/src/core/OutdatedPackagesProcessor.js +20 -0
  14. package/dist/src/core/SucceededResult.js +2 -0
  15. package/dist/src/core/index.js +17 -0
  16. package/dist/src/file/index.js +13 -0
  17. package/dist/src/file/readFile.js +12 -0
  18. package/dist/src/git/CommitMessageCreator.js +22 -0
  19. package/dist/src/git/Git.js +51 -0
  20. package/dist/src/git/GitRepository.js +41 -0
  21. package/dist/src/git/createBranchName.js +9 -0
  22. package/dist/src/git/index.js +16 -0
  23. package/dist/src/github/GitHub.js +94 -0
  24. package/dist/src/github/branch/finder/BranchFinder.js +12 -0
  25. package/dist/src/github/branch/finder/index.js +13 -0
  26. package/dist/src/github/branch/index.js +13 -0
  27. package/dist/src/github/createGitHub.js +13 -0
  28. package/dist/src/github/createOctokit.js +26 -0
  29. package/dist/src/github/errors/NotFoundError.js +10 -0
  30. package/dist/src/github/errors/index.js +13 -0
  31. package/dist/src/github/index.js +17 -0
  32. package/dist/src/github/label/creator/LabelCreator.js +46 -0
  33. package/dist/src/github/label/creator/index.js +13 -0
  34. package/dist/src/github/label/index.js +13 -0
  35. package/dist/src/github/pull-request/closer/PullRequestCloser.js +21 -0
  36. package/dist/src/github/pull-request/closer/index.js +13 -0
  37. package/dist/src/github/pull-request/creator/PullRequestCreator.js +45 -0
  38. package/dist/src/github/pull-request/creator/PullRequestTitleCreator.js +22 -0
  39. package/dist/src/github/pull-request/creator/createPullRequestBody.js +39 -0
  40. package/dist/src/github/pull-request/creator/index.js +14 -0
  41. package/dist/src/github/pull-request/finder/PullRequestFinder.js +27 -0
  42. package/dist/src/github/pull-request/finder/index.js +13 -0
  43. package/dist/src/github/pull-request/finder/isPullRequestByNpmUpdatePackage.js +7 -0
  44. package/dist/src/github/pull-request/index.js +15 -0
  45. package/dist/src/github/pull-request/metadata/PullRequestMetadata.js +15 -0
  46. package/dist/src/github/pull-request/metadata/createPullRequestMetadata.js +19 -0
  47. package/dist/src/github/pull-request/metadata/extractPullRequestMetadata.js +17 -0
  48. package/dist/src/github/pull-request/metadata/index.js +15 -0
  49. package/dist/src/json/index.js +13 -0
  50. package/dist/src/json/toJSON.js +14 -0
  51. package/dist/src/logger/LogLevel.js +15 -0
  52. package/dist/src/logger/Logger.js +2 -0
  53. package/dist/src/logger/createLogger.js +11 -0
  54. package/dist/src/logger/index.js +15 -0
  55. package/dist/src/main.js +112 -0
  56. package/dist/src/ncu/Ncu.js +71 -0
  57. package/dist/src/ncu/NcuResult.js +6 -0
  58. package/dist/src/ncu/index.js +13 -0
  59. package/dist/src/options/CLIOption.js +2 -0
  60. package/dist/src/options/OptionType.js +10 -0
  61. package/dist/src/options/Options.js +30 -0
  62. package/dist/src/options/cliOptions.js +61 -0
  63. package/dist/src/options/index.js +14 -0
  64. package/dist/src/options/initOptions.js +25 -0
  65. package/dist/src/options/toCommanderOption.js +32 -0
  66. package/dist/src/package-json/PackageMetadata.js +18 -0
  67. package/dist/src/package-json/PackageMetadataDependencies.js +6 -0
  68. package/dist/src/package-json/index.js +14 -0
  69. package/dist/src/package-json/parsePackageJson.js +15 -0
  70. package/dist/src/package-manager/Npm.js +18 -0
  71. package/dist/src/package-manager/PackageManager.js +2 -0
  72. package/dist/src/package-manager/PackageManagerName.js +10 -0
  73. package/dist/src/package-manager/Yarn.js +18 -0
  74. package/dist/src/package-manager/createPackageManager.js +15 -0
  75. package/dist/src/package-manager/index.js +17 -0
  76. package/dist/src/semver/SemVer.js +25 -0
  77. package/dist/src/semver/SemVerLevel.js +11 -0
  78. package/dist/src/semver/compareSemVers.js +16 -0
  79. package/dist/src/semver/index.js +15 -0
  80. package/dist/src/terminal/Terminal.js +14 -0
  81. package/dist/src/terminal/index.js +13 -0
  82. package/jest.config.ts +12 -0
  83. package/lint-staged.config.js +4 -0
  84. package/npm-update-package.code-workspace +10 -0
  85. package/package.json +1 -4
  86. package/src/bin.ts +22 -0
  87. package/src/core/FailedResult.ts +6 -0
  88. package/src/core/OutdatedPackage.ts +11 -0
  89. package/src/core/OutdatedPackageProcessor.ts +136 -0
  90. package/src/core/OutdatedPackagesProcessor.ts +35 -0
  91. package/src/core/SucceededResult.ts +7 -0
  92. package/src/core/index.ts +5 -0
  93. package/src/file/index.ts +1 -0
  94. package/src/file/readFile.ts +6 -0
  95. package/src/git/CommitMessageCreator.test.ts +17 -0
  96. package/src/git/CommitMessageCreator.ts +19 -0
  97. package/src/git/Git.ts +59 -0
  98. package/src/git/GitRepository.test.ts +82 -0
  99. package/src/git/GitRepository.ts +57 -0
  100. package/src/git/createBranchName.test.ts +14 -0
  101. package/src/git/createBranchName.ts +7 -0
  102. package/src/git/index.ts +4 -0
  103. package/src/github/GitHub.ts +198 -0
  104. package/src/github/branch/finder/BranchFinder.test.ts +21 -0
  105. package/src/github/branch/finder/BranchFinder.ts +9 -0
  106. package/src/github/branch/finder/index.ts +1 -0
  107. package/src/github/branch/index.ts +1 -0
  108. package/src/github/createGitHub.test.ts +16 -0
  109. package/src/github/createGitHub.ts +17 -0
  110. package/src/github/createOctokit.test.ts +27 -0
  111. package/src/github/createOctokit.ts +27 -0
  112. package/src/github/errors/NotFoundError.ts +11 -0
  113. package/src/github/errors/index.ts +1 -0
  114. package/src/github/index.ts +5 -0
  115. package/src/github/label/creator/LabelCreator.ts +71 -0
  116. package/src/github/label/creator/index.ts +1 -0
  117. package/src/github/label/index.ts +1 -0
  118. package/src/github/pull-request/closer/PullRequestCloser.test.ts +53 -0
  119. package/src/github/pull-request/closer/PullRequestCloser.ts +21 -0
  120. package/src/github/pull-request/closer/index.ts +1 -0
  121. package/src/github/pull-request/creator/PullRequestCreator.test.ts +98 -0
  122. package/src/github/pull-request/creator/PullRequestCreator.ts +84 -0
  123. package/src/github/pull-request/creator/PullRequestTitleCreator.test.ts +17 -0
  124. package/src/github/pull-request/creator/PullRequestTitleCreator.ts +19 -0
  125. package/src/github/pull-request/creator/createPullRequestBody.test.ts +47 -0
  126. package/src/github/pull-request/creator/createPullRequestBody.ts +35 -0
  127. package/src/github/pull-request/creator/index.ts +2 -0
  128. package/src/github/pull-request/finder/PullRequestFinder.ts +27 -0
  129. package/src/github/pull-request/finder/index.ts +1 -0
  130. package/src/github/pull-request/finder/isPullRequestByNpmUpdatePackage.test.ts +24 -0
  131. package/src/github/pull-request/finder/isPullRequestByNpmUpdatePackage.ts +5 -0
  132. package/src/github/pull-request/index.ts +3 -0
  133. package/src/github/pull-request/metadata/PullRequestMetadata.ts +22 -0
  134. package/src/github/pull-request/metadata/createPullRequestMetadata.test.ts +31 -0
  135. package/src/github/pull-request/metadata/createPullRequestMetadata.ts +21 -0
  136. package/src/github/pull-request/metadata/extractPullRequestMetadata.test.ts +53 -0
  137. package/src/github/pull-request/metadata/extractPullRequestMetadata.ts +21 -0
  138. package/src/github/pull-request/metadata/index.ts +3 -0
  139. package/src/json/index.ts +1 -0
  140. package/src/json/toJSON.test.ts +65 -0
  141. package/src/json/toJSON.ts +13 -0
  142. package/src/logger/LogLevel.ts +13 -0
  143. package/src/logger/Logger.ts +1 -0
  144. package/src/logger/createLogger.ts +10 -0
  145. package/src/logger/index.ts +3 -0
  146. package/src/main.ts +149 -0
  147. package/src/ncu/Ncu.ts +84 -0
  148. package/src/ncu/NcuResult.ts +10 -0
  149. package/src/ncu/index.ts +1 -0
  150. package/src/options/CLIOption.ts +19 -0
  151. package/src/options/OptionType.ts +8 -0
  152. package/src/options/Options.ts +40 -0
  153. package/src/options/cliOptions.ts +60 -0
  154. package/src/options/index.ts +2 -0
  155. package/src/options/initOptions.ts +24 -0
  156. package/src/options/toCommanderOption.ts +35 -0
  157. package/src/package-json/PackageMetadata.ts +24 -0
  158. package/src/package-json/PackageMetadataDependencies.ts +10 -0
  159. package/src/package-json/index.ts +2 -0
  160. package/src/package-json/parsePackageJson.ts +15 -0
  161. package/src/package-manager/Npm.ts +17 -0
  162. package/src/package-manager/PackageManager.ts +5 -0
  163. package/src/package-manager/PackageManagerName.ts +8 -0
  164. package/src/package-manager/Yarn.ts +17 -0
  165. package/src/package-manager/createPackageManager.test.ts +27 -0
  166. package/src/package-manager/createPackageManager.ts +20 -0
  167. package/src/package-manager/index.ts +5 -0
  168. package/src/semver/SemVer.test.ts +17 -0
  169. package/src/semver/SemVer.ts +40 -0
  170. package/src/semver/SemVerLevel.ts +9 -0
  171. package/src/semver/compareSemVers.test.ts +21 -0
  172. package/src/semver/compareSemVers.ts +16 -0
  173. package/src/semver/index.ts +3 -0
  174. package/src/terminal/Terminal.ts +12 -0
  175. package/src/terminal/index.ts +1 -0
  176. package/tsconfig.base.json +7 -0
  177. package/tsconfig.build.json +12 -0
  178. package/tsconfig.json +9 -0
@@ -0,0 +1 @@
1
+ export * from './BranchFinder'
@@ -0,0 +1 @@
1
+ export * from './finder'
@@ -0,0 +1,16 @@
1
+ import { GitRepository } from '../git'
2
+ import { createGitHub } from './createGitHub'
3
+ import { GitHub } from './GitHub'
4
+
5
+ describe('createGitHub', () => {
6
+ it('returns new GitHub instance', () => {
7
+ const repository = GitRepository.of('https://github.com/npm-update-package/npm-update-package.git')
8
+ const token = 'token'
9
+ const github = createGitHub({
10
+ repository,
11
+ token
12
+ })
13
+
14
+ expect(github).toBeInstanceOf(GitHub)
15
+ })
16
+ })
@@ -0,0 +1,17 @@
1
+ import type { GitRepository } from '../git'
2
+ import { createOctokit } from './createOctokit'
3
+ import { GitHub } from './GitHub'
4
+
5
+ export const createGitHub = ({
6
+ repository,
7
+ token
8
+ }: {
9
+ repository: GitRepository
10
+ token: string
11
+ }): GitHub => {
12
+ const octokit = createOctokit({
13
+ repository,
14
+ token
15
+ })
16
+ return new GitHub(octokit)
17
+ }
@@ -0,0 +1,27 @@
1
+ import { Octokit } from '@octokit/rest'
2
+ import { GitRepository } from '../git'
3
+ import { createOctokit } from './createOctokit'
4
+
5
+ describe('createOctokit', () => {
6
+ const token = 'token'
7
+
8
+ it('returns new Octokit instance for GitHub.com if repository is GitHub.com', () => {
9
+ const repository = GitRepository.of('https://github.com/npm-update-package/npm-update-package.git')
10
+ const octokit = createOctokit({
11
+ repository,
12
+ token
13
+ })
14
+
15
+ expect(octokit).toBeInstanceOf(Octokit)
16
+ })
17
+
18
+ it('returns new Octokit instance for GitHub Enterprise if repository is not GitHub.com', () => {
19
+ const repository = GitRepository.of('https://git.example.com/npm-update-package/npm-update-package.git')
20
+ const octokit = createOctokit({
21
+ repository,
22
+ token
23
+ })
24
+
25
+ expect(octokit).toBeInstanceOf(Octokit)
26
+ })
27
+ })
@@ -0,0 +1,27 @@
1
+ import { Octokit } from '@octokit/rest'
2
+ import pkg from '../../package.json'
3
+ import type { GitRepository } from '../git'
4
+
5
+ export const createOctokit = ({
6
+ repository,
7
+ token
8
+ }: {
9
+ repository: GitRepository
10
+ token: string
11
+ }): Octokit => {
12
+ const auth = `token ${token}`
13
+ const userAgent = `${pkg.name}/${pkg.version}`
14
+
15
+ if (repository.isGitHubDotCom) {
16
+ return new Octokit({
17
+ auth,
18
+ userAgent
19
+ })
20
+ } else {
21
+ return new Octokit({
22
+ auth,
23
+ userAgent,
24
+ baseUrl: repository.apiEndPoint
25
+ })
26
+ }
27
+ }
@@ -0,0 +1,11 @@
1
+ import { RequestError } from '@octokit/request-error'
2
+ import { StatusCodes } from 'http-status-codes'
3
+
4
+ export interface NotFoundError extends RequestError {
5
+ status: StatusCodes.NOT_FOUND
6
+ }
7
+
8
+ // TODO: Add test
9
+ export const isNotFoundError = (value: unknown): value is NotFoundError => {
10
+ return value instanceof RequestError && value.status === StatusCodes.NOT_FOUND
11
+ }
@@ -0,0 +1 @@
1
+ export * from './NotFoundError'
@@ -0,0 +1,5 @@
1
+ export * from './branch'
2
+ export * from './createGitHub'
3
+ export * from './errors'
4
+ export * from './label'
5
+ export * from './pull-request'
@@ -0,0 +1,71 @@
1
+ import type { GitRepository } from '../../../git'
2
+ import type { Logger } from '../../../logger'
3
+ import { isNotFoundError } from '../../errors'
4
+ import type {
5
+ GitHub,
6
+ Label
7
+ } from '../../GitHub'
8
+
9
+ // TODO: Add test
10
+ export class LabelCreator {
11
+ private readonly github: GitHub
12
+ private readonly gitRepo: GitRepository
13
+ private readonly logger: Logger
14
+
15
+ constructor ({
16
+ github,
17
+ gitRepo,
18
+ logger
19
+ }: {
20
+ github: GitHub
21
+ gitRepo: GitRepository
22
+ logger: Logger
23
+ }) {
24
+ this.github = github
25
+ this.gitRepo = gitRepo
26
+ this.logger = logger
27
+ }
28
+
29
+ async create ({
30
+ name,
31
+ description,
32
+ color
33
+ }: {
34
+ name: string
35
+ description?: string
36
+ color?: string
37
+ }): Promise<void> {
38
+ const label = await this.fetchLabel(name)
39
+
40
+ if (label !== undefined) {
41
+ this.logger.info(`Skip creating ${name} label because it already exists.`)
42
+ return
43
+ }
44
+
45
+ await this.github.createLabel({
46
+ owner: this.gitRepo.owner,
47
+ repo: this.gitRepo.name,
48
+ name,
49
+ description,
50
+ color
51
+ })
52
+ this.logger.info(`${name} label has created.`)
53
+ }
54
+
55
+ private async fetchLabel (name: string): Promise<Label | undefined> {
56
+ try {
57
+ return await this.github.fetchLabel({
58
+ owner: this.gitRepo.owner,
59
+ repo: this.gitRepo.name,
60
+ name
61
+ })
62
+ } catch (e) {
63
+ if (isNotFoundError(e)) {
64
+ this.logger.warn(e)
65
+ return undefined
66
+ } else {
67
+ throw e
68
+ }
69
+ }
70
+ }
71
+ }
@@ -0,0 +1 @@
1
+ export * from './LabelCreator'
@@ -0,0 +1 @@
1
+ export * from './creator'
@@ -0,0 +1,53 @@
1
+ import type {
2
+ GitHub,
3
+ PullRequest
4
+ } from '../../GitHub'
5
+ import { PullRequestCloser } from './PullRequestCloser'
6
+
7
+ describe('PullRequestCloser', () => {
8
+ describe('close', () => {
9
+ const githubClosePullRequestMock = jest.fn()
10
+ const githubDeleteBranchMock = jest.fn()
11
+
12
+ const github = {
13
+ closePullRequest: githubClosePullRequestMock,
14
+ deleteBranch: githubDeleteBranchMock
15
+ } as unknown as GitHub
16
+
17
+ afterEach(() => {
18
+ githubClosePullRequestMock.mockReset()
19
+ githubDeleteBranchMock.mockReset()
20
+ })
21
+
22
+ it('closes pull request', async () => {
23
+ const pullRequest = {
24
+ number: 1,
25
+ head: {
26
+ ref: 'new-topic'
27
+ },
28
+ base: {
29
+ repo: {
30
+ name: 'npm-update-package',
31
+ owner: {
32
+ login: 'npm-update-package'
33
+ }
34
+ }
35
+ }
36
+ } as unknown as PullRequest
37
+
38
+ const pullRequestCreator = new PullRequestCloser(github)
39
+ await pullRequestCreator.close(pullRequest)
40
+
41
+ expect(githubClosePullRequestMock).toBeCalledWith({
42
+ owner: pullRequest.base.repo.owner.login,
43
+ repo: pullRequest.base.repo.name,
44
+ pullNumber: pullRequest.number
45
+ })
46
+ expect(githubDeleteBranchMock).toBeCalledWith({
47
+ owner: pullRequest.base.repo.owner.login,
48
+ repo: pullRequest.base.repo.name,
49
+ branch: pullRequest.head.ref
50
+ })
51
+ })
52
+ })
53
+ })
@@ -0,0 +1,21 @@
1
+ import type {
2
+ GitHub,
3
+ PullRequest
4
+ } from '../../GitHub'
5
+
6
+ export class PullRequestCloser {
7
+ constructor (private readonly github: GitHub) {}
8
+
9
+ async close (pullRequest: PullRequest): Promise<void> {
10
+ await this.github.closePullRequest({
11
+ owner: pullRequest.base.repo.owner.login,
12
+ repo: pullRequest.base.repo.name,
13
+ pullNumber: pullRequest.number
14
+ })
15
+ await this.github.deleteBranch({
16
+ owner: pullRequest.base.repo.owner.login,
17
+ repo: pullRequest.base.repo.name,
18
+ branch: pullRequest.head.ref
19
+ })
20
+ }
21
+ }
@@ -0,0 +1 @@
1
+ export * from './PullRequestCloser'
@@ -0,0 +1,98 @@
1
+ import type { OutdatedPackage } from '../../../core'
2
+ import type { GitRepository } from '../../../git'
3
+ import {
4
+ createLogger,
5
+ LogLevel
6
+ } from '../../../logger'
7
+ import type {
8
+ GitHub,
9
+ Repository as GitHubRepository
10
+ } from '../../GitHub'
11
+ import * as createPullRequestBodyModule from './createPullRequestBody'
12
+ import { PullRequestCreator } from './PullRequestCreator'
13
+ import type { PullRequestTitleCreator } from './PullRequestTitleCreator'
14
+
15
+ describe('PullRequestCreator', () => {
16
+ describe('create', () => {
17
+ const pullRequestTitleCreatorCreateMock = jest.fn()
18
+ const githubCreatePullRequestMock = jest.fn()
19
+ const githubAddLabelsMock = jest.fn()
20
+ const githubRequestReviewersMock = jest.fn()
21
+ const createPullRequestBodySpy = jest.spyOn(createPullRequestBodyModule, 'createPullRequestBody')
22
+
23
+ const github = {
24
+ createPullRequest: githubCreatePullRequestMock,
25
+ addLabels: githubAddLabelsMock,
26
+ requestReviewers: githubRequestReviewersMock
27
+ } as unknown as GitHub
28
+ const gitRepo = {
29
+ owner: 'repository owner',
30
+ name: 'repository name'
31
+ } as unknown as GitRepository
32
+ const githubRepo = {
33
+ default_branch: 'master'
34
+ } as unknown as GitHubRepository
35
+ const pullRequestTitleCreator = {
36
+ create: pullRequestTitleCreatorCreateMock
37
+ } as unknown as PullRequestTitleCreator
38
+ const logger = createLogger(LogLevel.Off)
39
+ const outdatedPackage = {} as unknown as OutdatedPackage
40
+ const branchName = 'branch name'
41
+
42
+ afterEach(() => {
43
+ pullRequestTitleCreatorCreateMock.mockReset()
44
+ githubCreatePullRequestMock.mockReset()
45
+ githubAddLabelsMock.mockReset()
46
+ githubRequestReviewersMock.mockReset()
47
+ createPullRequestBodySpy.mockReset()
48
+ })
49
+
50
+ it('creates pull request', async () => {
51
+ const title = 'pull request title'
52
+ pullRequestTitleCreatorCreateMock.mockReturnValue(title)
53
+ const body = 'pull request body'
54
+ createPullRequestBodySpy.mockReturnValue(body)
55
+ const pullRequest = {
56
+ number: 1
57
+ }
58
+ githubCreatePullRequestMock.mockResolvedValue(pullRequest)
59
+
60
+ const reviewers = ['npm-update-package']
61
+ const pullRequestCreator = new PullRequestCreator({
62
+ github,
63
+ gitRepo,
64
+ githubRepo,
65
+ pullRequestTitleCreator,
66
+ logger,
67
+ reviewers
68
+ })
69
+ await pullRequestCreator.create({
70
+ outdatedPackage,
71
+ branchName
72
+ })
73
+
74
+ expect(pullRequestTitleCreatorCreateMock).toBeCalledWith(outdatedPackage)
75
+ expect(createPullRequestBodySpy).toBeCalledWith(outdatedPackage)
76
+ expect(githubCreatePullRequestMock).toBeCalledWith({
77
+ owner: gitRepo.owner,
78
+ repo: gitRepo.name,
79
+ baseBranch: githubRepo.default_branch,
80
+ headBranch: branchName,
81
+ title,
82
+ body
83
+ })
84
+ expect(githubAddLabelsMock).toBeCalledWith({
85
+ owner: gitRepo.owner,
86
+ repo: gitRepo.name,
87
+ issueNumber: pullRequest.number,
88
+ labels: ['npm-update-package']
89
+ })
90
+ expect(githubRequestReviewersMock).toBeCalledWith({
91
+ owner: gitRepo.owner,
92
+ repo: gitRepo.name,
93
+ pullNumber: pullRequest.number,
94
+ reviewers
95
+ })
96
+ })
97
+ })
98
+ })
@@ -0,0 +1,84 @@
1
+ import type { OutdatedPackage } from '../../../core'
2
+ import type { GitRepository } from '../../../git'
3
+ import type { Logger } from '../../../logger'
4
+ import type {
5
+ CreatedPullRequest,
6
+ GitHub,
7
+ Repository as GitHubRepository
8
+ } from '../../GitHub'
9
+ import { createPullRequestBody } from './createPullRequestBody'
10
+ import type { PullRequestTitleCreator } from './PullRequestTitleCreator'
11
+
12
+ export class PullRequestCreator {
13
+ private readonly github: GitHub
14
+ private readonly gitRepo: GitRepository
15
+ private readonly githubRepo: GitHubRepository
16
+ private readonly pullRequestTitleCreator: PullRequestTitleCreator
17
+ private readonly logger: Logger
18
+ private readonly reviewers: string[] | undefined
19
+
20
+ constructor ({
21
+ github,
22
+ gitRepo,
23
+ githubRepo,
24
+ pullRequestTitleCreator,
25
+ logger,
26
+ reviewers
27
+ }: {
28
+ github: GitHub
29
+ gitRepo: GitRepository
30
+ githubRepo: GitHubRepository
31
+ pullRequestTitleCreator: PullRequestTitleCreator
32
+ logger: Logger
33
+ reviewers?: string[]
34
+ }) {
35
+ this.github = github
36
+ this.gitRepo = gitRepo
37
+ this.githubRepo = githubRepo
38
+ this.pullRequestTitleCreator = pullRequestTitleCreator
39
+ this.logger = logger
40
+ this.reviewers = reviewers
41
+ }
42
+
43
+ async create ({
44
+ outdatedPackage,
45
+ branchName
46
+ }: {
47
+ outdatedPackage: OutdatedPackage
48
+ branchName: string
49
+ }): Promise<CreatedPullRequest> {
50
+ const title = this.pullRequestTitleCreator.create(outdatedPackage)
51
+ this.logger.debug(`title=${title}`)
52
+
53
+ const body = createPullRequestBody(outdatedPackage)
54
+ this.logger.debug(`body=${body}`)
55
+
56
+ const pullRequest = await this.github.createPullRequest({
57
+ owner: this.gitRepo.owner,
58
+ repo: this.gitRepo.name,
59
+ baseBranch: this.githubRepo.default_branch,
60
+ headBranch: branchName,
61
+ title,
62
+ body
63
+ })
64
+ this.logger.debug(`pullRequest=${JSON.stringify(pullRequest)}`)
65
+
66
+ await this.github.addLabels({
67
+ owner: this.gitRepo.owner,
68
+ repo: this.gitRepo.name,
69
+ issueNumber: pullRequest.number,
70
+ labels: ['npm-update-package']
71
+ })
72
+
73
+ if (this.reviewers !== undefined) {
74
+ await this.github.requestReviewers({
75
+ owner: this.gitRepo.owner,
76
+ repo: this.gitRepo.name,
77
+ pullNumber: pullRequest.number,
78
+ reviewers: this.reviewers
79
+ })
80
+ }
81
+
82
+ return pullRequest
83
+ }
84
+ }
@@ -0,0 +1,17 @@
1
+ import { SemVer } from '../../../semver'
2
+ import { PullRequestTitleCreator } from './PullRequestTitleCreator'
3
+
4
+ describe('PullRequestTitleCreator', () => {
5
+ describe('create', () => {
6
+ it('returns pull request title', () => {
7
+ const pullRequestTitleCreator = new PullRequestTitleCreator('chore(deps): {{level}} update {{{packageName}}} from {{currentVersion}} to v{{newVersion}}')
8
+ const actual = pullRequestTitleCreator.create({
9
+ name: '@npm-update-package/example',
10
+ currentVersion: SemVer.of('1.0.0'),
11
+ newVersion: SemVer.of('2.0.0'),
12
+ level: 'major'
13
+ })
14
+ expect(actual).toBe('chore(deps): major update @npm-update-package/example from 1.0.0 to v2.0.0')
15
+ })
16
+ })
17
+ })
@@ -0,0 +1,19 @@
1
+ import { render } from 'mustache'
2
+ import type { OutdatedPackage } from '../../../core'
3
+
4
+ export class PullRequestTitleCreator {
5
+ constructor (private readonly template: string) {}
6
+
7
+ create (outdatedPackage: OutdatedPackage): string {
8
+ const packageName = outdatedPackage.name
9
+ const currentVersion = outdatedPackage.currentVersion.version
10
+ const newVersion = outdatedPackage.newVersion.version
11
+ const level = outdatedPackage.level
12
+ return render(this.template, {
13
+ packageName,
14
+ currentVersion,
15
+ newVersion,
16
+ level
17
+ })
18
+ }
19
+ }
@@ -0,0 +1,47 @@
1
+
2
+ import pkg from '../../../../package.json'
3
+ import { SemVer } from '../../../semver'
4
+ import { createPullRequestBody } from './createPullRequestBody'
5
+
6
+ describe('createPullRequestBody', () => {
7
+ it('returns pull request body', () => {
8
+ const actual = createPullRequestBody({
9
+ name: '@npm-update-package/example',
10
+ currentVersion: SemVer.of('1.0.0'),
11
+ newVersion: SemVer.of('2.0.0'),
12
+ level: 'major'
13
+ })
14
+ expect(actual).toBe(`This PR updates these packages:
15
+
16
+ |Package|Level|Current version|New version|
17
+ |---|---|---|---|
18
+ |[@npm-update-package/example](https://www.npmjs.com/package/@npm-update-package/example)|major|\`1.0.0\`|\`2.0.0\`|
19
+
20
+ <details>
21
+ <summary>Metadata</summary>
22
+
23
+ **Don't remove or edit this section because it will be used by npm-update-package.**
24
+
25
+ <div id="npm-update-package-metadata">
26
+
27
+ \`\`\`json
28
+ {
29
+ "version": "${pkg.version}",
30
+ "packages": [
31
+ {
32
+ "name": "@npm-update-package/example",
33
+ "currentVersion": "1.0.0",
34
+ "newVersion": "2.0.0",
35
+ "level": "major"
36
+ }
37
+ ]
38
+ }
39
+ \`\`\`
40
+
41
+ </div>
42
+ </details>
43
+
44
+ ---
45
+ This PR has been generated by [${pkg.name}](${pkg.homepage}) v${pkg.version}`)
46
+ })
47
+ })
@@ -0,0 +1,35 @@
1
+
2
+ import pkg from '../../../../package.json'
3
+ import type { OutdatedPackage } from '../../../core'
4
+ import { toJSON } from '../../../json'
5
+ import { createPullRequestMetadata } from '../metadata'
6
+
7
+ export const createPullRequestBody = (outdatedPackage: OutdatedPackage): string => {
8
+ const currentVersion = outdatedPackage.currentVersion.version
9
+ const newVersion = outdatedPackage.newVersion.version
10
+ const packageName = outdatedPackage.name
11
+ const level = outdatedPackage.level
12
+ const metadata = toJSON(createPullRequestMetadata([outdatedPackage]), { pretty: true })
13
+ return `This PR updates these packages:
14
+
15
+ |Package|Level|Current version|New version|
16
+ |---|---|---|---|
17
+ |[${packageName}](https://www.npmjs.com/package/${packageName})|${level}|\`${currentVersion}\`|\`${newVersion}\`|
18
+
19
+ <details>
20
+ <summary>Metadata</summary>
21
+
22
+ **Don't remove or edit this section because it will be used by npm-update-package.**
23
+
24
+ <div id="npm-update-package-metadata">
25
+
26
+ \`\`\`json
27
+ ${metadata}
28
+ \`\`\`
29
+
30
+ </div>
31
+ </details>
32
+
33
+ ---
34
+ This PR has been generated by [${pkg.name}](${pkg.homepage}) v${pkg.version}`
35
+ }
@@ -0,0 +1,2 @@
1
+ export * from './PullRequestCreator'
2
+ export * from './PullRequestTitleCreator'
@@ -0,0 +1,27 @@
1
+ import type { PullRequest } from '../../GitHub'
2
+ import { extractPullRequestMetadata } from '../metadata'
3
+ import { isPullRequestByNpmUpdatePackage } from './isPullRequestByNpmUpdatePackage'
4
+
5
+ // TODO: Add test
6
+ export class PullRequestFinder {
7
+ constructor (private readonly pullRequests: PullRequest[]) {}
8
+
9
+ findByPackageName (packageName: string): PullRequest[] {
10
+ return this.pullRequests
11
+ .filter(isPullRequestByNpmUpdatePackage)
12
+ .filter(({ body }) => {
13
+ if (body === null) {
14
+ return false
15
+ }
16
+
17
+ const metadata = extractPullRequestMetadata(body)
18
+
19
+ if (metadata === undefined) {
20
+ return false
21
+ }
22
+
23
+ const { packages } = metadata
24
+ return packages.some(({ name }) => name === packageName)
25
+ })
26
+ }
27
+ }
@@ -0,0 +1 @@
1
+ export * from './PullRequestFinder'
@@ -0,0 +1,24 @@
1
+ import type { PullRequest } from '../../GitHub'
2
+ import { isPullRequestByNpmUpdatePackage } from './isPullRequestByNpmUpdatePackage'
3
+
4
+ describe('isPullRequestByNpmUpdatePackage', () => {
5
+ it('returns true if pull request has label `npm-update-package`', () => {
6
+ const pullRequest = {
7
+ labels: [
8
+ {
9
+ name: 'npm-update-package'
10
+ }
11
+ ]
12
+ } as unknown as PullRequest
13
+
14
+ expect(isPullRequestByNpmUpdatePackage(pullRequest)).toBe(true)
15
+ })
16
+
17
+ it('returns false if pull request does not have label `npm-update-package`', () => {
18
+ const pullRequest = {
19
+ labels: []
20
+ } as unknown as PullRequest
21
+
22
+ expect(isPullRequestByNpmUpdatePackage(pullRequest)).toBe(false)
23
+ })
24
+ })
@@ -0,0 +1,5 @@
1
+ import type { PullRequest } from '../../GitHub'
2
+
3
+ export const isPullRequestByNpmUpdatePackage = (pullRequest: PullRequest): boolean => {
4
+ return pullRequest.labels.some(({ name }) => name === 'npm-update-package')
5
+ }
@@ -0,0 +1,3 @@
1
+ export * from './closer'
2
+ export * from './creator'
3
+ export * from './finder'
@@ -0,0 +1,22 @@
1
+ import {
2
+ array,
3
+ literal,
4
+ string,
5
+ type,
6
+ union,
7
+ type TypeOf
8
+ } from 'io-ts'
9
+ import { SemVerLevel } from '../../../semver'
10
+
11
+ const PullRequestMetadata = type({
12
+ version: string,
13
+ packages: array(type({
14
+ name: string,
15
+ currentVersion: string,
16
+ newVersion: string,
17
+ level: union([literal(SemVerLevel.Major), literal(SemVerLevel.Minor), literal(SemVerLevel.Patch)])
18
+ }))
19
+ })
20
+ // eslint-disable-next-line @typescript-eslint/no-redeclare
21
+ export type PullRequestMetadata = TypeOf<typeof PullRequestMetadata>
22
+ export const isPullRequestMetadata = PullRequestMetadata.is