diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index c63b1354..73d7caf3 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -18,7 +18,7 @@ jobs: with: node-version: 16 - run: yarn --ignore-scripts - - run: yarn lint + - run: yarn lint:js lint-rust: runs-on: ubuntu-latest steps: diff --git a/.gitignore b/.gitignore index e94b6dec..d24cb08a 100644 --- a/.gitignore +++ b/.gitignore @@ -11,4 +11,7 @@ public/ # Added by cargo /target -book \ No newline at end of file +# Generated during build +/src/libRs.d.ts + +book diff --git a/Cargo.lock b/Cargo.lock index 8df59388..5c58e065 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,15 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "aho-corasick" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +dependencies = [ + "memchr", +] + [[package]] name = "autocfg" version = "1.0.1" @@ -37,9 +46,9 @@ checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" [[package]] name = "bytemuck" -version = "1.7.2" +version = "1.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72957246c41db82b8ef88a5486143830adeb8227ef9837740bdec67724cf2c5b" +checksum = "439989e6b8c38d1b6570a384ef1e49c8848128f5a97f3914baef02920842712f" [[package]] name = "byteorder" @@ -57,6 +66,22 @@ dependencies = [ "rgb", ] +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "ctor" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccc0a48a9b826acdf4028595adc9db92caea352f7af011a3034acd172a52a0aa" +dependencies = [ + "quote", + "syn", +] + [[package]] name = "digest" version = "0.8.1" @@ -104,9 +129,15 @@ dependencies = [ [[package]] name = "itoa" -version = "0.4.8" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" +checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "matches" @@ -116,7 +147,7 @@ checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" [[package]] name = "matrix-hookshot" -version = "0.1.0" +version = "1.0.0" dependencies = [ "contrast", "hex", @@ -143,39 +174,63 @@ dependencies = [ ] [[package]] -name = "napi" -version = "1.7.10" +name = "memchr" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9050238b713b3c5dd5ae1613da1ccefe4061c03992f9e9bbe43b7d473ba4bd3c" +checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" + +[[package]] +name = "napi" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4cfe7fef533df6323a5aa17d75cb162850f2b045adabb9922bfbd234426a1bb" dependencies = [ + "ctor", + "lazy_static", "napi-sys", "serde", "serde_json", - "winapi", + "windows", ] [[package]] name = "napi-build" -version = "1.1.1" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87375bacff0768dd606ccf870eae936efd21e3245af9e7b37ae44f969d48be8a" +checksum = "ebd4419172727423cf30351406c54f6cc1b354a2cfb4f1dba3e6cd07f6d5522b" [[package]] name = "napi-derive" -version = "1.1.2" +version = "2.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ee880798e942fc785e2e234544b9db578019a1d7676f45dad7f38d432ab0fe4" +checksum = "1fb47b1f5f021abe96fcb84e7977f46c0aa645904c18cdb7b3a031e61899bf48" dependencies = [ + "convert_case", + "napi-derive-backend", "proc-macro2", "quote", "syn", ] [[package]] -name = "napi-sys" -version = "1.1.2" +name = "napi-derive-backend" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67cf20e0081fea04e044aa4adf74cfea8ddc0324eec2894b1c700f4cafc72a56" +checksum = "487c39117657211e9bf93acade9363eac61ceead142e4906d15ff08d29fa448d" +dependencies = [ + "convert_case", + "once_cell", + "proc-macro2", + "quote", + "regex", + "syn", +] + +[[package]] +name = "napi-sys" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a385494dac3c52cbcacb393bb3b42669e7db8ab240c7ad5115f549eb061f2cc" [[package]] name = "num-traits" @@ -186,6 +241,12 @@ dependencies = [ "autocfg", ] +[[package]] +name = "once_cell" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5" + [[package]] name = "opaque-debug" version = "0.2.3" @@ -200,48 +261,65 @@ checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" [[package]] name = "proc-macro2" -version = "1.0.32" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43" +checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" dependencies = [ "unicode-xid", ] [[package]] name = "quote" -version = "1.0.10" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05" +checksum = "47aa80447ce4daf1717500037052af176af5d38cc3e571d9ec1c7353fc10c87d" dependencies = [ "proc-macro2", ] [[package]] -name = "rgb" -version = "0.8.29" +name = "regex" +version = "1.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a27fa03bb1e3e2941f52d4a555a395a72bf79b0a85fbbaab79447050c97d978c" +checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" + +[[package]] +name = "rgb" +version = "0.8.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a374af9a0e5fdcdd98c1c7b64f05004f9ea2555b6c75f211daa81268a3c50f1" dependencies = [ "bytemuck", ] [[package]] name = "ryu" -version = "1.0.5" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" +checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" [[package]] name = "serde" -version = "1.0.130" +version = "1.0.132" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" +checksum = "8b9875c23cf305cd1fd7eb77234cbb705f21ea6a72c637a5c6db5fe4b8e7f008" [[package]] name = "serde_derive" -version = "1.0.130" +version = "1.0.132" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b" +checksum = "ecc0db5cb2556c0e558887d9bbdcf6ac4471e83ff66cf696e5419024d1606276" dependencies = [ "proc-macro2", "quote", @@ -250,9 +328,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.71" +version = "1.0.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "063bf466a64011ac24040a49009724ee60a57da1b437617ceb32e53ad61bfb19" +checksum = "bcbd0344bc6533bc7ec56df11d42fb70f1b912351c0825ccb7211b59d8af7cf5" dependencies = [ "itoa", "ryu", @@ -261,9 +339,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.81" +version = "1.0.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2afee18b8beb5a596ecb4a2dce128c719b4ba399d34126b9e4396e3f9860966" +checksum = "ecb2e6da8ee5eb9a61068762a32fa9619cc591ceb055b3687f4cd4051ec2e06b" dependencies = [ "proc-macro2", "quote", @@ -287,9 +365,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "typenum" -version = "1.14.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec" +checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" [[package]] name = "unicode-bidi" @@ -325,23 +403,44 @@ dependencies = [ ] [[package]] -name = "winapi" -version = "0.3.9" +name = "windows" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +checksum = "aac7fef12f4b59cd0a29339406cc9203ab44e440ddff6b3f5a41455349fa9cf3" dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_msvc", ] [[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" +name = "windows_aarch64_msvc" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +checksum = "c3d027175d00b01e0cbeb97d6ab6ebe03b12330a35786cbaca5252b1c4bf5d9b" [[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" +name = "windows_i686_gnu" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +checksum = "8793f59f7b8e8b01eda1a652b2697d87b93097198ae85f823b969ca5b89bba58" + +[[package]] +name = "windows_i686_msvc" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8602f6c418b67024be2996c512f5f995de3ba417f4c75af68401ab8756796ae4" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3d615f419543e0bd7d2b3323af0d86ff19cbc4f816e6453f36a2c2ce889c354" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d95421d9ed3672c280884da53201a5c46b7b2765ca6faf34b0d71cf34a3561" diff --git a/Cargo.toml b/Cargo.toml index c50cf382..8f8c6dcf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,14 +1,14 @@ [package] name = "matrix-hookshot" -version = "0.1.0" +version = "1.0.0" edition = "2021" [lib] crate-type = ["cdylib"] [dependencies] -napi = {version="1", features=["serde-json"]} -napi-derive = "1" +napi = {version="2", features=["serde-json"]} +napi-derive = "2" url = "2" serde_json = "1" serde = "1" diff --git a/build.rs b/build.rs index 9fc23678..9851810a 100644 --- a/build.rs +++ b/build.rs @@ -1,5 +1,4 @@ -extern crate napi_build; - fn main() { - napi_build::setup(); + use napi_build::setup; + setup(); } diff --git a/changelog.d/111.misc b/changelog.d/111.misc new file mode 100644 index 00000000..42ee437b --- /dev/null +++ b/changelog.d/111.misc @@ -0,0 +1 @@ +Update to npai-rs@2 diff --git a/package.json b/package.json index e207dade..ee0ca48c 100644 --- a/package.json +++ b/package.json @@ -16,10 +16,11 @@ "scripts": { "build:web": "snowpack build", "build:app": "tsc --project tsconfig.json", - "build:app:rs": "napi build --release ./lib", + "build:app:rs": "napi build --dts ../src/libRs.d.ts --release ./lib", + "build:app:fix-defs": "ts-node scripts/definitions-fixer.ts src/libRs.d.ts", "build:docs": "ts-node scripts/build-metrics-docs.ts > docs/metrics.md && mdbook build", "dev:web": "snowpack dev", - "build": "yarn run build:web && yarn run build:app:rs && yarn run build:app", + "build": "yarn run build:web && yarn run build:app:rs && yarn run build:app:fix-defs && yarn run build:app", "prepare": "yarn build", "start": "node --require source-map-support/register lib/App/BridgeApp.js", "start:app": "node --require source-map-support/register lib/App/BridgeApp.js", @@ -59,7 +60,7 @@ }, "devDependencies": { "@fontsource/open-sans": "^4.2.2", - "@napi-rs/cli": "^1.3.5", + "@napi-rs/cli": "^2.2.0", "@prefresh/snowpack": "^3.1.2", "@snowpack/plugin-typescript": "^1.2.1", "@types/chai": "^4.2.22", diff --git a/scripts/definitions-fixer.ts b/scripts/definitions-fixer.ts new file mode 100644 index 00000000..90808c2d --- /dev/null +++ b/scripts/definitions-fixer.ts @@ -0,0 +1,19 @@ +/* eslint-disable no-console */ +// Workaround to https://github.com/napi-rs/napi-rs/issues/986 +import { promises as fs } from "fs"; + +async function processDefFile() { + const path = process.argv[process.argv.length-1]; + // Read the whole file in to prevent us writing over ourselves. + const file = await fs.readFile(path, "utf-8"); + const out = await fs.open(path, 'w'); + for (const line of file.split('\n')) { + const match = / {2}(\w+\.[\w.-]+):/g.exec(line); + out.write((match ? line.replace(match[1], `"${match[1]}"`) : line) + "\n"); + } +} + +processDefFile().catch((ex) => { + console.error('Failed to process def file!', ex); + process.exit(1); +}) diff --git a/src/FormatUtil.rs b/src/FormatUtil.rs deleted file mode 100644 index 128a9453..00000000 --- a/src/FormatUtil.rs +++ /dev/null @@ -1,170 +0,0 @@ -use crate::Jira; -use crate::Jira::types::{JiraIssue, JiraIssueLight}; -use contrast; -use md5::{Digest, Md5}; -use napi::{CallContext, Env, Error as NapiError, JsObject, JsString, JsUnknown, Status}; -use rgb::RGB; -use std::fmt::Write; - -#[derive(Serialize, Debug, Deserialize)] -struct IssueLabelDetail { - color: Option, - name: String, - description: Option, -} - -pub fn get_module(env: Env) -> Result { - let mut root_module = env.create_object()?; - root_module.create_named_method( - "get_partial_body_for_jira_issue", - get_partial_body_for_jira_issue, - )?; - root_module.create_named_method("format_labels", format_labels)?; - root_module.create_named_method("hash_id", hash_id)?; - Ok(root_module) -} - -fn parse_rgb(input_color: String) -> Result { - let chunk_size; - let color; - if input_color.starts_with('#') { - let mut chars = input_color.chars(); - chars.next(); - color = String::from_iter(chars); - } else { - color = input_color; - } - match color.len() { - 6 => { - chunk_size = 2; - } - 3 => { - chunk_size = 1; - } - _ => { - return Err(NapiError::new( - Status::InvalidArg, - format!("color '{}' is invalid", color).to_string(), - )); - } - } - let rgb = color - .as_bytes() - .chunks(chunk_size) - .map(std::str::from_utf8) - .collect::, _>>() - .unwrap(); - let r = u8::from_str_radix(rgb[0], 16).unwrap(); - let g = u8::from_str_radix(rgb[1], 16).unwrap(); - let b = u8::from_str_radix(rgb[2], 16).unwrap(); - Ok(RGB::new(r, g, b)) -} - -#[js_function(1)] -pub fn format_labels(ctx: CallContext) -> Result { - let array: JsObject = ctx.get::(0)?; - if array.is_array()? != true { - return Err(NapiError::new( - Status::InvalidArg, - "labels is not an array".to_string(), - )); - } - let mut plain = String::new(); - let mut html = String::new(); - let mut i = 0; - while array.has_element(i)? { - let label: IssueLabelDetail = ctx - .env - .from_js_value(array.get_element_unchecked::(i)?)?; - - if i != 0 { - plain.push_str(", "); - html.push_str(" "); - } - plain.push_str(&label.name); - - // HTML - html.push_str(" { - write!(html, " data-mx-bg-color=\"#{}\"", color).unwrap(); - // Determine the constrast - let color_rgb = parse_rgb(color)?; - let contrast_color; - if contrast::contrast::(color_rgb, RGB::new(0, 0, 0)) > 4.5 { - contrast_color = "#000000"; - } else { - contrast_color = "#FFFFFF"; - } - write!(html, " data-mx-color=\"{}\"", contrast_color).unwrap(); - } - None => {} - } - match label.description { - Some(description) => { - write!(html, " title=\"{}\"", description).unwrap(); - } - None => {} - } - html.push_str(">"); - html.push_str(&label.name); - html.push_str(""); - i += 1; - } - - let mut body = ctx.env.create_object()?; - body.set_named_property("plain", ctx.env.create_string_from_std(plain)?)?; - body.set_named_property("html", ctx.env.create_string_from_std(html)?)?; - Ok(body) -} - -/// Generate a URL for a given Jira Issue object. -#[js_function(1)] -pub fn get_partial_body_for_jira_issue(ctx: CallContext) -> Result { - let jira_issue: JiraIssue = ctx.env.from_js_value(ctx.get::(0)?)?; - let light = JiraIssueLight { - _self: jira_issue._self, - key: jira_issue.key, - }; - let mut body = ctx.env.create_object()?; - let url = Jira::utils::generate_jira_web_link_from_issue(&light)?; - body.set_named_property("external_url", ctx.env.create_string_from_std(url)?)?; - - let mut jira_issue_result = ctx.env.create_object()?; - let mut jira_project = ctx.env.create_object()?; - - jira_issue_result.set_named_property("id", ctx.env.create_string_from_std(jira_issue.id)?)?; - jira_issue_result.set_named_property("key", ctx.env.create_string_from_std(light.key)?)?; - jira_issue_result - .set_named_property("api_url", ctx.env.create_string_from_std(light._self)?)?; - - jira_project.set_named_property( - "id", - ctx.env - .create_string_from_std(jira_issue.fields.project.id)?, - )?; - jira_project.set_named_property( - "key", - ctx.env - .create_string_from_std(jira_issue.fields.project.key)?, - )?; - jira_project.set_named_property( - "api_url", - ctx.env - .create_string_from_std(jira_issue.fields.project._self)?, - )?; - - body.set_named_property("uk.half-shot.matrix-hookshot.jira.issue", jira_issue_result)?; - body.set_named_property("uk.half-shot.matrix-hookshot.jira.project", jira_project)?; - Ok(body) -} - -/// Generate a URL for a given Jira Issue object. -#[js_function(1)] -pub fn hash_id(ctx: CallContext) -> Result { - let id = ctx.get::(0)?; - let mut hasher = Md5::new(); - hasher.input(id.into_utf8()?.as_str()?); - let result = hex::encode(hasher.result()); - ctx.env.create_string_from_std(result) -} diff --git a/src/FormatUtil.ts b/src/FormatUtil.ts index b7478019..45279760 100644 --- a/src/FormatUtil.ts +++ b/src/FormatUtil.ts @@ -4,7 +4,7 @@ import emoji from "node-emoji"; // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore import { JiraIssue } from './Jira/Types'; -import { format_util } from "./libRs"; +import { formatLabels, getPartialBodyForJiraIssue, hashId } from "./libRs"; interface IMinimalRepository { id: number; @@ -115,14 +115,14 @@ export class FormatUtil { } public static formatLabels(labels: ILabel[] = []): { plain: string, html: string } { - return format_util.format_labels(labels); + return formatLabels(labels); } public static getPartialBodyForJiraIssue(issue: JiraIssue) { - return format_util.get_partial_body_for_jira_issue(issue); + return getPartialBodyForJiraIssue(issue); } public static hashId(id: string) { - return format_util.hash_id(id); + return hashId(id); } } diff --git a/src/Gitlab/Client.ts b/src/Gitlab/Client.ts index e11250ab..16b6c21d 100644 --- a/src/Gitlab/Client.ts +++ b/src/Gitlab/Client.ts @@ -3,6 +3,7 @@ import { GitLabInstance } from "../Config/Config"; import { GetIssueResponse, GetUserResponse, CreateIssueOpts, CreateIssueResponse, GetIssueOpts, EditIssueOpts, GetTodosResponse, EventsOpts, CreateIssueNoteOpts, CreateIssueNoteResponse } from "./Types"; import LogWrapper from "../LogWrapper"; import { URLSearchParams } from "url"; +import UserAgent from "../UserAgent"; const log = new LogWrapper("GitLabClient"); export class GitLabClient { @@ -23,7 +24,7 @@ export class GitLabClient { return { headers: { "Authorization": `Bearer ${this.token}`, - "User-Agent": "matrix-hookshot v0.0.1", + "User-Agent": UserAgent, }, baseURL: this.instanceUrl }; @@ -104,4 +105,4 @@ export class GitLabClient { createForIssue: this.createIssueNote.bind(this), } } -} \ No newline at end of file +} diff --git a/src/Jira/index.ts b/src/Jira/index.ts index 7216c94e..150cd904 100644 --- a/src/Jira/index.ts +++ b/src/Jira/index.ts @@ -1,3 +1,3 @@ -import { jira } from "../libRs"; +import * as libRs from "../libRs"; -export const generateJiraWebLinkFromIssue = jira.utils.generate_jira_web_link_from_issue; \ No newline at end of file +export const generateJiraWebLinkFromIssue = libRs.generateJiraWeblinkFromIssue; diff --git a/src/Jira/mod.rs b/src/Jira/mod.rs index d66497fc..b4ab6a6a 100644 --- a/src/Jira/mod.rs +++ b/src/Jira/mod.rs @@ -1,14 +1,2 @@ -use napi::{Env, Error as NapiError, JsObject}; pub mod types; pub mod utils; - -pub fn get_module(env: Env) -> Result { - let mut root_module = env.create_object()?; - let mut utils_module = env.create_object()?; - utils_module.create_named_method( - "generate_jira_web_link_from_issue", - utils::js_generate_jira_web_link_from_issue, - )?; - root_module.set_named_property("utils", utils_module)?; - Ok(root_module) -} diff --git a/src/Jira/types.rs b/src/Jira/types.rs index 80c25f59..68df4652 100644 --- a/src/Jira/types.rs +++ b/src/Jira/types.rs @@ -1,4 +1,5 @@ #[derive(Serialize, Debug, Deserialize)] +#[napi(object)] pub struct JiraProject { #[serde(rename = "self")] pub _self: String, @@ -7,6 +8,7 @@ pub struct JiraProject { } #[derive(Serialize, Debug, Deserialize)] +#[napi(object)] pub struct JiraIssue { #[serde(rename = "self")] @@ -17,13 +19,36 @@ pub struct JiraIssue { } #[derive(Serialize, Debug, Deserialize)] +#[napi(object)] pub struct JiraIssueFields { pub project: JiraProject, } #[derive(Serialize, Debug, Deserialize)] +#[napi(object)] pub struct JiraIssueLight { #[serde(rename = "self")] pub _self: String, pub key: String, } + +#[derive(Serialize, Debug, Deserialize)] +#[napi(object)] +pub struct JiraIssueSimpleItem { + pub id: String, + pub key: String, + #[napi(js_name = "api_url")] + pub api_url: String, +} +#[derive(Serialize, Debug, Deserialize)] +#[napi(object)] +pub struct JiraIssueMessageBody { + #[serde(rename = "uk.half-shot.matrix-hookshot.jira.issue")] + #[napi(js_name = "uk.half-shot.matrix-hookshot.jira.issue")] + pub jira_issue: JiraIssueSimpleItem, + #[serde(rename = "uk.half-shot.matrix-hookshot.jira.project")] + #[napi(js_name = "uk.half-shot.matrix-hookshot.jira.project")] + pub jira_project: JiraIssueSimpleItem, + #[napi(js_name = "external_url")] + pub external_url: String, +} diff --git a/src/Jira/utils.rs b/src/Jira/utils.rs index c466f291..13179851 100644 --- a/src/Jira/utils.rs +++ b/src/Jira/utils.rs @@ -1,19 +1,15 @@ use super::types::JiraIssueLight; -use napi::{CallContext, Error as NapiError, JsString, JsUnknown, Status}; +use napi::bindgen_prelude::*; +use napi_derive::napi; use url::Url; /// Generate a URL for a given Jira Issue object. -#[js_function(1)] -pub fn js_generate_jira_web_link_from_issue(ctx: CallContext) -> Result { - let jira_issue: JiraIssueLight = ctx.env.from_js_value(ctx.get::(0)?)?; - match generate_jira_web_link_from_issue(&jira_issue) { - Ok(url) => ctx.env.create_string_from_std(url), - Err(err) => Err(NapiError::new(Status::Unknown, err.to_string())), - } +#[napi(js_name = "generateJiraWeblinkFromIssue")] +pub fn js_generate_jira_web_link_from_issue(jira_issue: JiraIssueLight) -> Result { + return generate_jira_web_link_from_issue(&jira_issue); } -/// Generate a URL for a given Jira Issue object. -pub fn generate_jira_web_link_from_issue(jira_issue: &JiraIssueLight) -> Result { +pub fn generate_jira_web_link_from_issue(jira_issue: &JiraIssueLight) -> Result { let result = Url::parse(&jira_issue._self); match result { Ok(url) => Ok(format!( @@ -22,6 +18,6 @@ pub fn generate_jira_web_link_from_issue(jira_issue: &JiraIssueLight) -> Result< url.host_str().unwrap(), jira_issue.key )), - Err(err) => Err(NapiError::new(Status::Unknown, err.to_string())), + Err(err) => Err(Error::new(Status::Unknown, err.to_string())), } } diff --git a/src/UserAgent.ts b/src/UserAgent.ts new file mode 100644 index 00000000..c4b0f174 --- /dev/null +++ b/src/UserAgent.ts @@ -0,0 +1,2 @@ +const UserAgent = "matrix-hookshot/1.0.0 (+https://github.com/half-shot/matrix-hookshot)"; +export default UserAgent; diff --git a/src/format_util.rs b/src/format_util.rs new file mode 100644 index 00000000..f5b6737a --- /dev/null +++ b/src/format_util.rs @@ -0,0 +1,155 @@ +use crate::Jira; +use crate::Jira::types::{JiraIssue, JiraIssueLight, JiraIssueMessageBody, JiraIssueSimpleItem}; +use contrast; +use md5::{Digest, Md5}; +use napi::bindgen_prelude::*; +use napi_derive::napi; +use rgb::RGB; +use std::fmt::Write; + +#[derive(Serialize, Debug, Deserialize)] +#[napi(object)] +pub struct IssueLabelDetail { + pub color: Option, + pub name: String, + pub description: Option, +} + +#[napi(object)] +pub struct MatrixMessageFormatResult { + pub html: String, + pub plain: String, +} + +fn parse_rgb(input_color: String) -> Result { + let chunk_size; + let color; + if input_color.starts_with('#') { + let mut chars = input_color.chars(); + chars.next(); + color = String::from_iter(chars); + } else { + color = input_color; + } + match color.len() { + 6 => { + chunk_size = 2; + } + 3 => { + chunk_size = 1; + } + _ => { + return Err(Error::new( + Status::InvalidArg, + format!("color '{}' is invalid", color).to_string(), + )); + } + } + let mut rgb = RGB::default(); + let i = 0; + for color_byte in color.as_bytes().chunks(chunk_size) { + let val = std::str::from_utf8(color_byte) + .map_err(|e| { + Error::new( + Status::InvalidArg, + format!("UTF8Error '{}' when converting rgb component", e).to_string(), + ) + }) + .and_then(|v| { + u8::from_str_radix(v, 16).map_err(|e| { + Error::new( + Status::InvalidArg, + format!("Integer parse error '{}' when converting rgb component", e) + .to_string(), + ) + }) + })?; + if i == 0 { + rgb.r = val; + } else if i == 1 { + rgb.g = val; + } else if i == 2 { + rgb.b = val; + } + } + Ok(rgb) +} + +#[napi] +pub fn format_labels(array: Vec) -> Result { + let mut plain = String::new(); + let mut html = String::new(); + let mut i = 0; + for label in array { + if i != 0 { + plain.push_str(", "); + html.push_str(" "); + } + plain.push_str(&label.name); + + // HTML + html.push_str(" { + write!(html, " data-mx-bg-color=\"#{}\"", color).unwrap(); + // Determine the constrast + let color_rgb = parse_rgb(color)?; + let contrast_color; + if contrast::contrast::(color_rgb, RGB::new(0, 0, 0)) > 4.5 { + contrast_color = "#000000"; + } else { + contrast_color = "#FFFFFF"; + } + write!(html, " data-mx-color=\"{}\"", contrast_color).unwrap(); + } + None => {} + } + match label.description { + Some(description) => { + write!(html, " title=\"{}\"", description).unwrap(); + } + None => {} + } + html.push_str(">"); + html.push_str(&label.name); + html.push_str(""); + i += 1; + } + + Ok(MatrixMessageFormatResult { + html: html, + plain: plain, + }) +} + +/// Generate a URL for a given Jira Issue object. +#[napi] +pub fn get_partial_body_for_jira_issue(jira_issue: JiraIssue) -> Result { + let light_issue = JiraIssueLight { + _self: jira_issue._self, + key: jira_issue.key, + }; + let external_url = Jira::utils::generate_jira_web_link_from_issue(&light_issue)?; + + Ok(JiraIssueMessageBody { + jira_issue: JiraIssueSimpleItem { + id: jira_issue.id, + key: light_issue.key, + api_url: light_issue._self, + }, + jira_project: JiraIssueSimpleItem { + id: jira_issue.fields.project.id, + key: jira_issue.fields.project.key, + api_url: jira_issue.fields.project._self, + }, + external_url: external_url, + }) +} + +/// Generate a URL for a given Jira Issue object. +#[napi] +pub fn hash_id(id: String) -> Result { + let mut hasher = Md5::new(); + hasher.input(id); + Ok(hex::encode(hasher.result())) +} diff --git a/src/lib.rs b/src/lib.rs index f949b41d..66e8423a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,16 +1,8 @@ -use napi::{Env, Error as NapiError, JsObject}; -mod FormatUtil; -mod Jira; +pub mod Jira; +pub mod format_util; #[macro_use] extern crate napi_derive; #[macro_use] extern crate serde_derive; - -#[module_exports] -fn init(mut exports: JsObject, env: Env) -> Result<(), NapiError> { - exports.set_named_property("jira", Jira::get_module(env)?)?; - exports.set_named_property("format_util", FormatUtil::get_module(env)?)?; - Ok(()) -} diff --git a/src/libRs.js b/src/libRs.js new file mode 100644 index 00000000..819a9c4e --- /dev/null +++ b/src/libRs.js @@ -0,0 +1,7 @@ +try { + // In production, we expect it co-located + module.exports = require('./matrix-hookshot-rs.node'); +} catch (ex) { + // When running under ts-node, it may not be co-located. + module.exports = require('../lib/matrix-hookshot-rs.node'); +} diff --git a/src/libRs.ts b/src/libRs.ts deleted file mode 100644 index e7e4401d..00000000 --- a/src/libRs.ts +++ /dev/null @@ -1,29 +0,0 @@ -/* eslint-disable camelcase */ -import { ILabel } from "./FormatUtil"; -import { JiraIssue } from "./Jira/Types"; - -// eslint-disable-next-line @typescript-eslint/no-var-requires -let rootModule; -try { - // In production, we expect it co-located - rootModule = require('./matrix-hookshot-rs.node'); -} catch (ex) { - // When running under ts-node, it may not be co-located. - rootModule = require('../lib/matrix-hookshot-rs.node'); -} - -interface FormatUtil { - get_partial_body_for_jira_issue: (issue: JiraIssue) => Record - format_labels: (labels: ILabel[]) => { plain: string, html: string } - hash_id: (id: string) => string -} - -interface JiraModule { - utils: { - generate_jira_web_link_from_issue: (issue: {self: string, key: string}) => string; - } -} - - -export const format_util = rootModule.format_util as FormatUtil; -export const jira = rootModule.jira as JiraModule; \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index ee6f2b02..44f944e7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -274,12 +274,10 @@ resolved "https://registry.yarnpkg.com/@isaacs/string-locale-compare/-/string-locale-compare-1.1.0.tgz#291c227e93fd407a96ecd59879a35809120e432b" integrity sha512-SQ7Kzhh9+D+ZW9MA0zkYv3VXhIDNx+LzM6EJ+/65I3QY+enU6Itte7E5XX7EWrqLW2FN4n06GWzBnPoC3th2aQ== -"@napi-rs/cli@^1.3.5": - version "1.3.5" - resolved "https://registry.yarnpkg.com/@napi-rs/cli/-/cli-1.3.5.tgz#89e4d97127edc4ed10a06637a43d27a1ed3c288d" - integrity sha512-Z0KZIciemioYODTyO908v2AtL8Zg4sohQDD+dyHeHmOiOfaez/y/xQ8XnpOHc2W5fRidKUW+MVWyTtpLTbKsqw== - dependencies: - inquirer "^8.1.3" +"@napi-rs/cli@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@napi-rs/cli/-/cli-2.2.0.tgz#0129406192c2dfff6e8fc3de0c8be1d2ec286e3f" + integrity sha512-lXOKq0EZWztzHIlpXhKG0Nrv/PDZAl/yBsqQTG0aDfdjGCJudtPgWLR7zzaJoYzkkdFJo0r+teYYzgC+cXB4KQ== "@nodelib/fs.scandir@2.1.5": version "2.1.5" @@ -1151,13 +1149,6 @@ ansi-colors@4.1.1, ansi-colors@^4.1.1: resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== -ansi-escapes@^4.2.1: - version "4.3.2" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" - integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== - dependencies: - type-fest "^0.21.3" - ansi-regex@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" @@ -1290,7 +1281,7 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== -base64-js@^1.1.2, base64-js@^1.3.1: +base64-js@^1.1.2: version "1.5.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== @@ -1346,15 +1337,6 @@ bintrees@1.0.1: resolved "https://registry.yarnpkg.com/bintrees/-/bintrees-1.0.1.tgz#0e655c9b9c2435eaab68bf4027226d2b55a34524" integrity sha1-DmVcm5wkNeqraL9AJyJtK1WjRSQ= -bl@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" - integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== - dependencies: - buffer "^5.5.0" - inherits "^2.0.4" - readable-stream "^3.4.0" - bluebird@^2.6.2: version "2.11.0" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-2.11.0.tgz#534b9033c022c9579c56ba3b3e5a5caafbb650e1" @@ -1446,14 +1428,6 @@ buffer-from@^1.0.0: resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== -buffer@^5.5.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" - integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== - dependencies: - base64-js "^1.3.1" - ieee754 "^1.1.13" - bufferutil@^4.0.2: version "4.0.5" resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.5.tgz#da9ea8166911cc276bf677b8aed2d02d31f59028" @@ -1564,7 +1538,7 @@ chalk@^2.0.0: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.1: +chalk@^4.0.0, chalk@^4.1.0: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== @@ -1572,11 +1546,6 @@ chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.1: ansi-styles "^4.1.0" supports-color "^7.1.0" -chardet@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" - integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== - check-error@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" @@ -1651,23 +1620,11 @@ clean-stack@^2.0.0: resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== -cli-cursor@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" - integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== - dependencies: - restore-cursor "^3.1.0" - cli-spinners@^2.5.0: version "2.6.1" resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.6.1.tgz#adc954ebe281c37a6319bfa401e6dd2488ffb70d" integrity sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g== -cli-width@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6" - integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw== - cliui@^7.0.2: version "7.0.4" resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" @@ -1684,11 +1641,6 @@ clone-response@^1.0.2: dependencies: mimic-response "^1.0.0" -clone@^1.0.2: - version "1.0.4" - resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" - integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= - cluster-key-slot@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/cluster-key-slot/-/cluster-key-slot-1.1.0.tgz#30474b2a981fb12172695833052bc0d01336d10d" @@ -1957,13 +1909,6 @@ default-browser-id@^2.0.0: pify "^2.3.0" untildify "^2.0.0" -defaults@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" - integrity sha1-xlYFHpgX2f8I7YgUd/P+QBnz730= - dependencies: - clone "^1.0.2" - defer-to-connect@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587" @@ -2444,15 +2389,6 @@ extend@~3.0.2: resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== -external-editor@^3.0.3: - version "3.1.0" - resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" - integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== - dependencies: - chardet "^0.7.0" - iconv-lite "^0.4.24" - tmp "^0.0.33" - extsprintf@1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" @@ -2506,13 +2442,6 @@ fecha@^4.2.0: resolved "https://registry.yarnpkg.com/fecha/-/fecha-4.2.1.tgz#0a83ad8f86ef62a091e22bb5a039cd03d23eecce" integrity sha512-MMMQ0ludy/nBs1/o0zVOiKTpG7qMbonKUzjJgQFEuvq6INZ1OraKPRAWkBq5vlKLOUMpmNYG1JoN3oDPUQ9m3Q== -figures@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" - integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== - dependencies: - escape-string-regexp "^1.0.5" - file-entry-cache@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" @@ -2974,7 +2903,7 @@ humanize-ms@^1.2.1: dependencies: ms "^2.0.0" -iconv-lite@0.4.24, iconv-lite@^0.4.24: +iconv-lite@0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== @@ -2998,11 +2927,6 @@ icss-utils@^5.0.0: resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== -ieee754@^1.1.13: - version "1.2.1" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" - integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== - ignore-walk@^3.0.3: version "3.0.4" resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.4.tgz#c9a09f69b7c7b479a5d74ac1a3c0d4236d2a6335" @@ -3051,7 +2975,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.4, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: +inherits@2, inherits@2.0.4, inherits@^2.0.3, inherits@~2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -3061,26 +2985,6 @@ inherits@2.0.1: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE= -inquirer@^8.1.3: - version "8.2.0" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-8.2.0.tgz#f44f008dd344bbfc4b30031f45d984e034a3ac3a" - integrity sha512-0crLweprevJ02tTuA6ThpoAERAGyVILC4sS74uib58Xf/zSr1/ZWtmm7D5CI+bSQEaA04f0K7idaHpQbSWgiVQ== - dependencies: - ansi-escapes "^4.2.1" - chalk "^4.1.1" - cli-cursor "^3.1.0" - cli-width "^3.0.0" - external-editor "^3.0.3" - figures "^3.0.0" - lodash "^4.17.21" - mute-stream "0.0.8" - ora "^5.4.1" - run-async "^2.4.0" - rxjs "^7.2.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - through "^2.3.6" - ioredis@^4.28.0: version "4.28.2" resolved "https://registry.yarnpkg.com/ioredis/-/ioredis-4.28.2.tgz#493ccd5d869fd0ec86c96498192718171f6c9203" @@ -3166,11 +3070,6 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: dependencies: is-extglob "^2.1.1" -is-interactive@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" - integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w== - is-lambda@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-lambda/-/is-lambda-1.0.1.tgz#3d9877899e6a53efc0160504cde15f82e6f061d5" @@ -3218,11 +3117,6 @@ is-typedarray@^1.0.0, is-typedarray@~1.0.0: resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= -is-unicode-supported@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" - integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== - is-valid-identifier@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/is-valid-identifier/-/is-valid-identifier-2.0.2.tgz#146d9dbf29821b8118580b039d2203aa4bd1da4b" @@ -3548,14 +3442,6 @@ log-symbols@4.0.0: dependencies: chalk "^4.0.0" -log-symbols@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" - integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== - dependencies: - chalk "^4.1.0" - is-unicode-supported "^0.1.0" - logform@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/logform/-/logform-2.3.0.tgz#a3997a05985de2ebd325ae0d166dffc9c6fe6b57" @@ -3905,11 +3791,6 @@ ms@2.1.3, ms@^2.0.0, ms@^2.1.1: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== -mute-stream@0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" - integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== - nanoid@3.1.20: version "3.1.20" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.20.tgz#badc263c6b1dcf14b71efaa85f6ab4c1d6cfc788" @@ -4112,7 +3993,7 @@ one-time@^1.0.0: dependencies: fn.name "1.x.x" -onetime@^5.1.0, onetime@^5.1.2: +onetime@^5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== @@ -4140,31 +4021,11 @@ optionator@^0.9.1: type-check "^0.4.0" word-wrap "^1.2.3" -ora@^5.4.1: - version "5.4.1" - resolved "https://registry.yarnpkg.com/ora/-/ora-5.4.1.tgz#1b2678426af4ac4a509008e5e4ac9e9959db9e18" - integrity sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ== - dependencies: - bl "^4.1.0" - chalk "^4.1.0" - cli-cursor "^3.1.0" - cli-spinners "^2.5.0" - is-interactive "^1.0.0" - is-unicode-supported "^0.1.0" - log-symbols "^4.1.0" - strip-ansi "^6.0.0" - wcwidth "^1.0.1" - os-homedir@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= -os-tmpdir@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" - integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= - p-cancelable@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.1.1.tgz#aab7fbd416582fa32a3db49859c122487c5ed2cf" @@ -4772,14 +4633,6 @@ responselike@^2.0.0: dependencies: lowercase-keys "^2.0.0" -restore-cursor@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" - integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== - dependencies: - onetime "^5.1.0" - signal-exit "^3.0.2" - retry@^0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" @@ -4818,11 +4671,6 @@ rollup@~2.37.1: optionalDependencies: fsevents "~2.1.2" -run-async@^2.4.0: - version "2.4.1" - resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" - integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== - run-parallel@^1.1.9: version "1.2.0" resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" @@ -4830,13 +4678,6 @@ run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" -rxjs@^7.2.0: - version "7.4.0" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.4.0.tgz#a12a44d7eebf016f5ff2441b87f28c9a51cebc68" - integrity sha512-7SQDi7xeTMCJpqViXh8gL/lebcwlp3d831F05+9B44A4B0WfsEwUQHR64gsH1kvJ+Ep/J9K2+n1hVl1CsGN23w== - dependencies: - tslib "~2.1.0" - safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" @@ -5285,18 +5126,6 @@ text-table@^0.2.0: resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= -through@^2.3.6: - version "2.3.8" - resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" - integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= - -tmp@^0.0.33: - version "0.0.33" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" - integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== - dependencies: - os-tmpdir "~1.0.2" - to-fast-properties@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" @@ -5365,11 +5194,6 @@ tslib@^2.2.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01" integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw== -tslib@~2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a" - integrity sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A== - tsutils@^3.21.0: version "3.21.0" resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" @@ -5406,11 +5230,6 @@ type-fest@^0.20.2: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== -type-fest@^0.21.3: - version "0.21.3" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" - integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== - type-is@~1.6.18: version "1.6.18" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" @@ -5552,13 +5371,6 @@ walk-up-path@^1.0.0: resolved "https://registry.yarnpkg.com/walk-up-path/-/walk-up-path-1.0.0.tgz#d4745e893dd5fd0dbb58dd0a4c6a33d9c9fec53e" integrity sha512-hwj/qMDUEjCU5h0xr90KGCf0tg0/LgJbmOWgrWKYlcJZM7XvquvUJZ0G/HMGr7F7OQMOUuPHWP9JpriinkAlkg== -wcwidth@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" - integrity sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g= - dependencies: - defaults "^1.0.3" - webidl-conversions@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"