source.ts 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. import { Octokit } from '@octokit/rest'
  2. import request from '../lib/request'
  3. export type SourceInfo = {
  4. version: string
  5. downloadUrl: string
  6. }
  7. export abstract class BaseSource {
  8. abstract getSourceInfo(): Promise<SourceInfo | undefined>
  9. protected getPlatformIdentifier() {
  10. switch (process.platform) {
  11. case 'win32':
  12. return 'windows-amd64.exe'
  13. case 'linux':
  14. return process.arch === 'arm64'
  15. ? 'linux-arm64'
  16. : process.arch === 'arm'
  17. ? 'linux-arm'
  18. : 'linux-amd64'
  19. case 'darwin':
  20. return 'darwin-amd64'
  21. default:
  22. throw new Error('Unsupported platform')
  23. }
  24. }
  25. }
  26. /**
  27. * Download mkcert from github.com
  28. */
  29. export class GithubSource extends BaseSource {
  30. public static create() {
  31. return new GithubSource()
  32. }
  33. private constructor() {
  34. super()
  35. }
  36. public async getSourceInfo(): Promise<SourceInfo | undefined> {
  37. const octokit = new Octokit()
  38. const { data } = await octokit.repos.getLatestRelease({
  39. owner: 'FiloSottile',
  40. repo: 'mkcert'
  41. })
  42. const platformIdentifier = this.getPlatformIdentifier()
  43. const version = data.tag_name
  44. const downloadUrl = data.assets.find(item =>
  45. item.name.includes(platformIdentifier)
  46. )?.browser_download_url
  47. if (!(version && downloadUrl)) {
  48. return undefined
  49. }
  50. return {
  51. downloadUrl,
  52. version
  53. }
  54. }
  55. }
  56. /**
  57. * Download mkcert from coding.net
  58. *
  59. * @see {https://help.coding.net/openapi}
  60. */
  61. export class CodingSource extends BaseSource {
  62. public static CODING_API = 'https://e.coding.net/open-api'
  63. public static CODING_AUTHORIZATION =
  64. 'token 000f7831ec425079439b0f55f55c729c9280d66e'
  65. public static CODING_PROJECT_ID = 8524617
  66. public static REPOSITORY = 'mkcert'
  67. public static create() {
  68. return new CodingSource()
  69. }
  70. private constructor() {
  71. super()
  72. }
  73. private async request(data: any) {
  74. return request({
  75. data,
  76. method: 'POST',
  77. url: CodingSource.CODING_API,
  78. headers: {
  79. Authorization: CodingSource.CODING_AUTHORIZATION
  80. }
  81. })
  82. }
  83. /**
  84. * Get filename of Coding.net artifacts
  85. *
  86. * @see https://liuweigl.coding.net/p/github/artifacts/885241/generic/packages
  87. *
  88. * @returns name
  89. */
  90. private getPackageName() {
  91. return `mkcert-${this.getPlatformIdentifier()}`
  92. }
  93. async getSourceInfo(): Promise<SourceInfo | undefined> {
  94. /**
  95. * @see https://help.coding.net/openapi#e2106ec64e75af66f188463b1bb7e165
  96. */
  97. const { data: VersionData } = await this.request({
  98. Action: 'DescribeArtifactVersionList',
  99. ProjectId: CodingSource.CODING_PROJECT_ID,
  100. Repository: CodingSource.REPOSITORY,
  101. Package: this.getPackageName(),
  102. PageSize: 1
  103. })
  104. const version = VersionData.Response.Data.InstanceSet[0]?.Version
  105. if (!version) {
  106. return undefined
  107. }
  108. /**
  109. * @see https://help.coding.net/openapi#63ad6bc7469373cef575e92bb92be71e
  110. */
  111. const { data: FileData } = await this.request({
  112. Action: 'DescribeArtifactFileDownloadUrl',
  113. ProjectId: CodingSource.CODING_PROJECT_ID,
  114. Repository: CodingSource.REPOSITORY,
  115. Package: this.getPackageName(),
  116. PackageVersion: version
  117. })
  118. const downloadUrl = FileData.Response.Url
  119. if (!downloadUrl) {
  120. return undefined
  121. }
  122. return {
  123. downloadUrl,
  124. version
  125. }
  126. }
  127. }