Support napi v2 (#111)

* Export a sensible user agent

* Completely rewrite rust portions to be napi v2 compatible

* Format rust files

* Only lint TS files when running lint-node

* Don't include autogenerated typings in the tree

* changelog

* Autofix generated rust dependencies due to a bug in napi@2

* Fix for multiple runs

* Fix format_util file name

* Make script generic

* lint
This commit is contained in:
Will Hunt 2022-01-02 01:54:57 +00:00 committed by GitHub
parent 694d50826e
commit e6dd83ac5b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 395 additions and 494 deletions

View File

@ -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:

3
.gitignore vendored
View File

@ -11,4 +11,7 @@ public/
# Added by cargo
/target
# Generated during build
/src/libRs.d.ts
book

191
Cargo.lock generated
View File

@ -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"

View File

@ -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"

View File

@ -1,5 +1,4 @@
extern crate napi_build;
fn main() {
napi_build::setup();
use napi_build::setup;
setup();
}

1
changelog.d/111.misc Normal file
View File

@ -0,0 +1 @@
Update to npai-rs@2

View File

@ -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",

View File

@ -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);
})

View File

@ -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<String>,
name: String,
description: Option<String>,
}
pub fn get_module(env: Env) -> Result<JsObject, NapiError> {
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<rgb::RGB8, NapiError> {
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::<Result<Vec<&str>, _>>()
.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<JsObject, NapiError> {
let array: JsObject = ctx.get::<JsObject>(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::<JsUnknown>(i)?)?;
if i != 0 {
plain.push_str(", ");
html.push_str(" ");
}
plain.push_str(&label.name);
// HTML
html.push_str("<span");
match label.color {
Some(color) => {
write!(html, " data-mx-bg-color=\"#{}\"", color).unwrap();
// Determine the constrast
let color_rgb = parse_rgb(color)?;
let contrast_color;
if contrast::contrast::<u8, f32>(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("</span>");
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<JsObject, NapiError> {
let jira_issue: JiraIssue = ctx.env.from_js_value(ctx.get::<JsUnknown>(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<JsString, NapiError> {
let id = ctx.get::<JsString>(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)
}

View File

@ -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);
}
}

View File

@ -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
};

View File

@ -1,3 +1,3 @@
import { jira } from "../libRs";
import * as libRs from "../libRs";
export const generateJiraWebLinkFromIssue = jira.utils.generate_jira_web_link_from_issue;
export const generateJiraWebLinkFromIssue = libRs.generateJiraWeblinkFromIssue;

View File

@ -1,14 +1,2 @@
use napi::{Env, Error as NapiError, JsObject};
pub mod types;
pub mod utils;
pub fn get_module(env: Env) -> Result<JsObject, NapiError> {
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)
}

View File

@ -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,
}

View File

@ -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<JsString, NapiError> {
let jira_issue: JiraIssueLight = ctx.env.from_js_value(ctx.get::<JsUnknown>(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<String> {
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<String, NapiError> {
pub fn generate_jira_web_link_from_issue(jira_issue: &JiraIssueLight) -> Result<String> {
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())),
}
}

2
src/UserAgent.ts Normal file
View File

@ -0,0 +1,2 @@
const UserAgent = "matrix-hookshot/1.0.0 (+https://github.com/half-shot/matrix-hookshot)";
export default UserAgent;

155
src/format_util.rs Normal file
View File

@ -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<String>,
pub name: String,
pub description: Option<String>,
}
#[napi(object)]
pub struct MatrixMessageFormatResult {
pub html: String,
pub plain: String,
}
fn parse_rgb(input_color: String) -> Result<rgb::RGB8> {
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<IssueLabelDetail>) -> Result<MatrixMessageFormatResult> {
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("<span");
match label.color {
Some(color) => {
write!(html, " data-mx-bg-color=\"#{}\"", color).unwrap();
// Determine the constrast
let color_rgb = parse_rgb(color)?;
let contrast_color;
if contrast::contrast::<u8, f32>(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("</span>");
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<JiraIssueMessageBody> {
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<String> {
let mut hasher = Md5::new();
hasher.input(id);
Ok(hex::encode(hasher.result()))
}

View File

@ -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(())
}

7
src/libRs.js Normal file
View File

@ -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');
}

View File

@ -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<string, unknown>
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;

206
yarn.lock
View File

@ -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"