1import * as fs from "fs"
2import toml from "toml"
3import { schemeMeta } from "./colorSchemes"
4import { Meta, Verification } from "./themes/common/colorScheme"
5import https from "https"
6import crypto from "crypto"
7
8const accepted_licenses_file = `${__dirname}/../../script/licenses/zed-licenses.toml`
9
10// Use the cargo-about configuration file as the source of truth for supported licenses.
11function parseAcceptedToml(file: string): string[] {
12 let buffer = fs.readFileSync(file).toString()
13
14 let obj = toml.parse(buffer)
15
16 if (!Array.isArray(obj.accepted)) {
17 throw Error("Accepted license source is malformed")
18 }
19
20 return obj.accepted
21}
22
23function checkLicenses(schemeMeta: Meta[], licenses: string[]) {
24 for (let meta of schemeMeta) {
25 // FIXME: Add support for conjuctions and conditions
26 if (licenses.indexOf(meta.license.SPDX) < 0) {
27 throw Error(
28 `License for theme ${meta.name} (${meta.license.SPDX}) is not supported`
29 )
30 }
31 }
32}
33
34function getLicenseText(
35 schemeMeta: Meta[],
36 callback: (meta: Meta, license_text: string) => void
37) {
38 for (let meta of schemeMeta) {
39 if (typeof meta.license.license_text == "string") {
40 callback(meta, meta.license.license_text)
41 } else {
42 let license_text_obj: Verification = meta.license.license_text
43 // The following copied from the example code on nodejs.org:
44 // https://nodejs.org/api/http.html#httpgetoptions-callback
45 https
46 .get(license_text_obj.https_url, (res) => {
47 const { statusCode } = res
48
49 if (statusCode < 200 || statusCode >= 300) {
50 throw new Error(
51 `Failed to fetch license for: ${meta.name}, Status Code: ${statusCode}`
52 )
53 }
54
55 res.setEncoding("utf8")
56 let rawData = ""
57 res.on("data", (chunk) => {
58 rawData += chunk
59 })
60 res.on("end", () => {
61 const hash = crypto
62 .createHash("sha256")
63 .update(rawData)
64 .digest("hex")
65 if (license_text_obj.license_checksum == hash) {
66 callback(meta, rawData)
67 } else {
68 throw Error(
69 `Checksum for ${meta.name} did not match file downloaded from ${license_text_obj.https_url}`
70 )
71 }
72 })
73 })
74 .on("error", (e) => {
75 throw e
76 })
77 }
78 }
79}
80
81function writeLicense(schemeMeta: Meta, text: String) {
82 process.stdout.write(
83 `## [${schemeMeta.name}](${schemeMeta.url})\n\n${text}\n********************************************************************************\n\n`
84 )
85}
86
87const accepted_licenses = parseAcceptedToml(accepted_licenses_file)
88checkLicenses(schemeMeta, accepted_licenses)
89
90getLicenseText(schemeMeta, (meta, text) => {
91 writeLicense(meta, text)
92})