sdk tweaks (#2760)

* sdk tweaks

* update action result types

* accommodate new action response types

* fix: show action value labels

* Feature/get status effect (#2765)

* wip: get status

* feat: Add the get_status for effects

* feat: Do a callback

---------

Co-authored-by: J H <dragondef@gmail.com>

---------

Co-authored-by: Matt Hill <mattnine@protonmail.com>
Co-authored-by: waterplea <alexander@inkin.ru>
Co-authored-by: J H <dragondef@gmail.com>
This commit is contained in:
Aiden McClelland
2024-10-28 12:12:36 -06:00
committed by GitHub
parent 42cfd69463
commit 26ae0bf207
28 changed files with 871 additions and 456 deletions

View File

@@ -284,6 +284,9 @@ export function makeEffects(context: EffectContext): Effects {
> >
}, },
getStatus(...[o]: Parameters<T.Effects["getStatus"]>) {
return rpcRound("get-status", o) as ReturnType<T.Effects["getStatus"]>
},
setMainStatus(o: { status: "running" | "stopped" }): Promise<null> { setMainStatus(o: { status: "running" | "stopped" }): Promise<null> {
return rpcRound("set-main-status", o) as ReturnType< return rpcRound("set-main-status", o) as ReturnType<
T.Effects["setHealth"] T.Effects["setHealth"]

View File

@@ -245,10 +245,10 @@ const matchProperties = object({
function convertProperties( function convertProperties(
name: string, name: string,
value: PropertiesValue, value: PropertiesValue,
): T.ActionResultV1 { ): T.ActionResultMember {
if (value.type === "string") { if (value.type === "string") {
return { return {
type: "string", type: "single",
name, name,
description: value.description, description: value.description,
copyable: value.copyable || false, copyable: value.copyable || false,
@@ -258,9 +258,9 @@ function convertProperties(
} }
} }
return { return {
type: "object", type: "group",
name, name,
description: value.description || undefined, description: value.description,
value: Object.entries(value.value).map(([name, value]) => value: Object.entries(value.value).map(([name, value]) =>
convertProperties(name, value), convertProperties(name, value),
), ),
@@ -459,13 +459,14 @@ export class SystemForEmbassy implements System {
} else if (actionId === "properties") { } else if (actionId === "properties") {
return { return {
version: "1", version: "1",
type: "object", title: "Properties",
name: "Properties", message: null,
description: result: {
"Runtime information, credentials, and other values of interest", type: "group",
value: Object.entries(await this.properties(effects, timeoutMs)).map( value: Object.entries(await this.properties(effects, timeoutMs)).map(
([name, value]) => convertProperties(name, value), ([name, value]) => convertProperties(name, value),
), ),
},
} }
} else { } else {
return this.action(effects, actionId, input, timeoutMs) return this.action(effects, actionId, input, timeoutMs)
@@ -814,13 +815,13 @@ export class SystemForEmbassy implements System {
const actionProcedure = this.manifest.actions?.[actionId]?.implementation const actionProcedure = this.manifest.actions?.[actionId]?.implementation
const toActionResult = ({ const toActionResult = ({
message, message,
value = "", value,
copyable, copyable,
qr, qr,
}: U.ActionResult): T.ActionResult => ({ }: U.ActionResult): T.ActionResult => ({
version: "0", version: "0",
message, message,
value, value: value ?? null,
copyable, copyable,
qr, qr,
}) })

View File

@@ -1,3 +1,4 @@
use std::collections::BTreeMap;
use std::fmt; use std::fmt;
use clap::{CommandFactory, FromArgMatches, Parser}; use clap::{CommandFactory, FromArgMatches, Parser};
@@ -6,7 +7,6 @@ use models::PackageId;
use qrcode::QrCode; use qrcode::QrCode;
use rpc_toolkit::{from_fn_async, Context, HandlerExt, ParentHandler}; use rpc_toolkit::{from_fn_async, Context, HandlerExt, ParentHandler};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;
use tracing::instrument; use tracing::instrument;
use ts_rs::TS; use ts_rs::TS;
@@ -24,7 +24,7 @@ pub fn action_api<C: Context>() -> ParentHandler<C> {
from_fn_async(get_action_input) from_fn_async(get_action_input)
.with_display_serializable() .with_display_serializable()
.with_about("Get action input spec") .with_about("Get action input spec")
.with_call_remote::<CliContext>() .with_call_remote::<CliContext>(),
) )
.subcommand( .subcommand(
"run", "run",
@@ -37,7 +37,7 @@ pub fn action_api<C: Context>() -> ParentHandler<C> {
Ok(()) Ok(())
}) })
.with_about("Run service action") .with_about("Run service action")
.with_call_remote::<CliContext>() .with_call_remote::<CliContext>(),
) )
} }
@@ -121,83 +121,78 @@ impl fmt::Display for ActionResultV0 {
} }
} }
#[derive(Debug, Serialize, Deserialize, TS)]
#[serde(rename_all = "camelCase")]
pub struct ActionResultV1 {
pub title: String,
pub message: Option<String>,
pub result: Option<ActionResultValue>,
}
#[derive(Debug, Serialize, Deserialize, TS)]
#[serde(rename_all = "camelCase")]
pub struct ActionResultMember {
pub name: String,
pub description: Option<String>,
#[serde(flatten)]
#[ts(flatten)]
pub value: ActionResultValue,
}
#[derive(Debug, Serialize, Deserialize, TS)] #[derive(Debug, Serialize, Deserialize, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[serde(rename_all_fields = "camelCase")] #[serde(rename_all_fields = "camelCase")]
#[serde(tag = "type")] #[serde(tag = "type")]
pub enum ActionResultV1 { pub enum ActionResultValue {
String { Single {
name: String,
value: String, value: String,
description: Option<String>,
copyable: bool, copyable: bool,
qr: bool, qr: bool,
masked: bool, masked: bool,
}, },
Object { Group {
name: String, value: Vec<ActionResultMember>,
value: Vec<ActionResultV1>,
#[ts(optional)]
description: Option<String>,
}, },
} }
impl ActionResultV1 { impl ActionResultValue {
fn fmt_rec(&self, f: &mut fmt::Formatter<'_>, indent: usize) -> fmt::Result { fn fmt_rec(&self, f: &mut fmt::Formatter<'_>, indent: usize) -> fmt::Result {
match self { match self {
Self::String { Self::Single { value, qr, .. } => {
name, for _ in 0..indent {
value,
description,
qr,
..
} => {
for i in 0..indent {
write!(f, " ")?; write!(f, " ")?;
} }
write!(f, "{name}")?; write!(f, "{value}")?;
if let Some(description) = description { if *qr {
write!(f, ": {description}")?; use qrcode::render::unicode;
} writeln!(f)?;
if !value.is_empty() { for _ in 0..indent {
write!(f, ":\n")?;
for i in 0..indent {
write!(f, " ")?; write!(f, " ")?;
} }
write!(f, "{value}")?; write!(
if *qr { f,
use qrcode::render::unicode; "{}",
write!(f, "\n")?; QrCode::new(value.as_bytes())
for i in 0..indent { .unwrap()
write!(f, " ")?; .render::<unicode::Dense1x2>()
} .build()
write!( )?;
f,
"{}",
QrCode::new(value.as_bytes())
.unwrap()
.render::<unicode::Dense1x2>()
.build()
)?;
}
} }
} }
Self::Object { Self::Group { value } => {
name, for ActionResultMember {
value, name,
description, description,
} => { value,
for i in 0..indent { } in value
write!(f, " ")?; {
} for _ in 0..indent {
write!(f, "{name}")?;
if let Some(description) = description {
write!(f, ": {description}")?;
}
for value in value {
write!(f, ":\n")?;
for i in 0..indent {
write!(f, " ")?; write!(f, " ")?;
} }
write!(f, "{name}")?;
if let Some(description) = description {
write!(f, ": {description}")?;
}
writeln!(f, ":")?;
value.fmt_rec(f, indent + 1)?; value.fmt_rec(f, indent + 1)?;
} }
} }
@@ -207,7 +202,14 @@ impl ActionResultV1 {
} }
impl fmt::Display for ActionResultV1 { impl fmt::Display for ActionResultV1 {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.fmt_rec(f, 0) writeln!(f, "{}:", self.title)?;
if let Some(message) = &self.message {
writeln!(f, "{message}")?;
}
if let Some(result) = &self.result {
result.fmt_rec(f, 1)?;
}
Ok(())
} }
} }

View File

@@ -36,6 +36,7 @@ struct ServiceCallbackMap {
(NonDetachingJoinHandle<()>, Vec<CallbackHandler>), (NonDetachingJoinHandle<()>, Vec<CallbackHandler>),
>, >,
get_store: BTreeMap<PackageId, BTreeMap<JsonPointer, Vec<CallbackHandler>>>, get_store: BTreeMap<PackageId, BTreeMap<JsonPointer, Vec<CallbackHandler>>>,
get_status: BTreeMap<PackageId, Vec<CallbackHandler>>,
} }
impl ServiceCallbacks { impl ServiceCallbacks {
@@ -71,6 +72,10 @@ impl ServiceCallbacks {
}); });
!v.is_empty() !v.is_empty()
}); });
this.get_status.retain(|_, v| {
v.retain(|h| h.handle.is_active() && h.seed.strong_count() > 0);
!v.is_empty()
});
}) })
} }
@@ -220,6 +225,20 @@ impl ServiceCallbacks {
.push(handler); .push(handler);
}) })
} }
pub(super) fn add_get_status(&self, package_id: PackageId, handler: CallbackHandler) {
self.mutate(|this| this.get_status.entry(package_id).or_default().push(handler))
}
#[must_use]
pub fn get_status(&self, package_id: &PackageId) -> Option<CallbackHandlers> {
self.mutate(|this| {
if let Some(watched) = this.get_status.remove(package_id) {
Some(CallbackHandlers(watched))
} else {
None
}
.filter(|cb| !cb.0.is_empty())
})
}
pub(super) fn add_get_store( pub(super) fn add_get_store(
&self, &self,

View File

@@ -1,9 +1,11 @@
use std::str::FromStr; use std::str::FromStr;
use clap::builder::ValueParserFactory; use clap::builder::ValueParserFactory;
use models::FromStrParser; use models::{FromStrParser, PackageId};
use crate::service::effects::prelude::*; use crate::service::effects::prelude::*;
use crate::service::rpc::CallbackId;
use crate::status::MainStatus;
pub async fn restart( pub async fn restart(
context: EffectContext, context: EffectContext,
@@ -23,6 +25,46 @@ pub async fn shutdown(
Ok(()) Ok(())
} }
#[derive(Debug, Clone, Serialize, Deserialize, TS, Parser)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct GetStatusParams {
#[ts(optional)]
pub package_id: Option<PackageId>,
#[ts(optional)]
#[arg(skip)]
pub callback: Option<CallbackId>,
}
pub async fn get_status(
context: EffectContext,
GetStatusParams {
package_id,
callback,
}: GetStatusParams,
) -> Result<MainStatus, Error> {
let context = context.deref()?;
let id = package_id.unwrap_or_else(|| context.seed.id.clone());
let db = context.seed.ctx.db.peek().await;
let status = db
.as_public()
.as_package_data()
.as_idx(&id)
.or_not_found(&id)?
.as_status()
.de()?;
if let Some(callback) = callback {
let callback = callback.register(&context.seed.persistent_container);
context.seed.ctx.callbacks.add_get_status(
id,
super::callbacks::CallbackHandler::new(&context, callback),
);
}
Ok(status)
}
#[derive(Debug, Clone, Serialize, Deserialize, TS)] #[derive(Debug, Clone, Serialize, Deserialize, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[ts(export)] #[ts(export)]

View File

@@ -50,6 +50,12 @@ pub fn handler<C: Context>() -> ParentHandler<C> {
.no_display() .no_display()
.with_call_remote::<ContainerCliContext>(), .with_call_remote::<ContainerCliContext>(),
) )
.subcommand(
"get-status",
from_fn_async(control::get_status)
.no_display()
.with_call_remote::<ContainerCliContext>(),
)
// dependency // dependency
.subcommand( .subcommand(
"set-dependencies", "set-dependencies",

View File

@@ -1,6 +1,8 @@
use std::sync::Arc; use std::sync::Arc;
use std::time::Duration; use std::time::Duration;
use imbl::vector;
use super::start_stop::StartStop; use super::start_stop::StartStop;
use super::ServiceActorSeed; use super::ServiceActorSeed;
use crate::prelude::*; use crate::prelude::*;
@@ -45,7 +47,8 @@ async fn service_actor_loop(
let id = &seed.id; let id = &seed.id;
let kinds = current.borrow().kinds(); let kinds = current.borrow().kinds();
if let Err(e) = async { if let Err(e) = async {
seed.ctx let major_changes_state = seed
.ctx
.db .db
.mutate(|d| { .mutate(|d| {
if let Some(i) = d.as_public_mut().as_package_data_mut().as_idx_mut(&id) { if let Some(i) = d.as_public_mut().as_package_data_mut().as_idx_mut(&id) {
@@ -89,11 +92,22 @@ async fn service_actor_loop(
.. ..
} => MainStatus::Stopped, } => MainStatus::Stopped,
}; };
let previous = i.as_status().de()?;
i.as_status_mut().ser(&main_status)?; i.as_status_mut().ser(&main_status)?;
return Ok(previous
.major_changes(&main_status)
.then_some((previous, main_status)));
} }
Ok(()) Ok(None)
}) })
.await?; .await?;
if let Some((previous, new_state)) = major_changes_state {
if let Some(callbacks) = seed.ctx.callbacks.get_status(id) {
callbacks
.call(vector![to_value(&previous)?, to_value(&new_state)?])
.await?;
}
}
seed.synchronized.notify_waiters(); seed.synchronized.notify_waiters();
match kinds { match kinds {

View File

@@ -66,6 +66,20 @@ impl MainStatus {
} }
} }
pub fn major_changes(&self, other: &Self) -> bool {
match (self, other) {
(MainStatus::Running { .. }, MainStatus::Running { .. }) => false,
(MainStatus::Starting { .. }, MainStatus::Starting { .. }) => false,
(MainStatus::Stopping, MainStatus::Stopping) => false,
(MainStatus::Stopped, MainStatus::Stopped) => false,
(MainStatus::Restarting, MainStatus::Restarting) => false,
(MainStatus::Restoring, MainStatus::Restoring) => false,
(MainStatus::BackingUp { .. }, MainStatus::BackingUp { .. }) => false,
(MainStatus::Error { .. }, MainStatus::Error { .. }) => false,
_ => true,
}
}
pub fn backing_up(self) -> Self { pub fn backing_up(self) -> Self {
MainStatus::BackingUp { MainStatus::BackingUp {
on_complete: if self.running() { on_complete: if self.running() {

View File

@@ -14,6 +14,7 @@ import {
ServiceInterface, ServiceInterface,
ActionRequest, ActionRequest,
RequestActionParams, RequestActionParams,
MainStatus,
} from "./osBindings" } from "./osBindings"
import { StorePath } from "./util/PathBuilder" import { StorePath } from "./util/PathBuilder"
import { import {
@@ -61,6 +62,11 @@ export type Effects = {
restart(): Promise<null> restart(): Promise<null>
/** stop this service's main function */ /** stop this service's main function */
shutdown(): Promise<null> shutdown(): Promise<null>
/** ask the host os what the service's current status is */
getStatus(options: {
packageId?: PackageId
callback?: () => void
}): Promise<MainStatus>
/** indicate to the host os what runstate the service is in */ /** indicate to the host os what runstate the service is in */
setMainStatus(options: SetMainStatus): Promise<null> setMainStatus(options: SetMainStatus): Promise<null>

View File

@@ -0,0 +1,15 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type ActionResultMember = {
name: string
description: string | null
} & (
| {
type: "single"
value: string
copyable: boolean
qr: boolean
masked: boolean
}
| { type: "group"; value: Array<ActionResultMember> }
)

View File

@@ -1,18 +1,8 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { ActionResultValue } from "./ActionResultValue"
export type ActionResultV1 = export type ActionResultV1 = {
| { title: string
type: "string" message: string | null
name: string result: ActionResultValue | null
value: string }
description: string | null
copyable: boolean
qr: boolean
masked: boolean
}
| {
type: "object"
name: string
value: Array<ActionResultV1>
description?: string
}

View File

@@ -0,0 +1,12 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { ActionResultMember } from "./ActionResultMember"
export type ActionResultValue =
| {
type: "single"
value: string
copyable: boolean
qr: boolean
masked: boolean
}
| { type: "group"; value: Array<ActionResultMember> }

View File

@@ -0,0 +1,5 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { CallbackId } from "./CallbackId"
import type { PackageId } from "./PackageId"
export type GetStatusParams = { packageId?: PackageId; callback?: CallbackId }

View File

@@ -7,9 +7,11 @@ export { ActionRequestEntry } from "./ActionRequestEntry"
export { ActionRequestInput } from "./ActionRequestInput" export { ActionRequestInput } from "./ActionRequestInput"
export { ActionRequestTrigger } from "./ActionRequestTrigger" export { ActionRequestTrigger } from "./ActionRequestTrigger"
export { ActionRequest } from "./ActionRequest" export { ActionRequest } from "./ActionRequest"
export { ActionResultMember } from "./ActionResultMember"
export { ActionResult } from "./ActionResult" export { ActionResult } from "./ActionResult"
export { ActionResultV0 } from "./ActionResultV0" export { ActionResultV0 } from "./ActionResultV0"
export { ActionResultV1 } from "./ActionResultV1" export { ActionResultV1 } from "./ActionResultV1"
export { ActionResultValue } from "./ActionResultValue"
export { ActionSeverity } from "./ActionSeverity" export { ActionSeverity } from "./ActionSeverity"
export { ActionVisibility } from "./ActionVisibility" export { ActionVisibility } from "./ActionVisibility"
export { AddAdminParams } from "./AddAdminParams" export { AddAdminParams } from "./AddAdminParams"
@@ -79,6 +81,7 @@ export { GetServiceInterfaceParams } from "./GetServiceInterfaceParams"
export { GetServicePortForwardParams } from "./GetServicePortForwardParams" export { GetServicePortForwardParams } from "./GetServicePortForwardParams"
export { GetSslCertificateParams } from "./GetSslCertificateParams" export { GetSslCertificateParams } from "./GetSslCertificateParams"
export { GetSslKeyParams } from "./GetSslKeyParams" export { GetSslKeyParams } from "./GetSslKeyParams"
export { GetStatusParams } from "./GetStatusParams"
export { GetStoreParams } from "./GetStoreParams" export { GetStoreParams } from "./GetStoreParams"
export { GetSystemSmtpParams } from "./GetSystemSmtpParams" export { GetSystemSmtpParams } from "./GetSystemSmtpParams"
export { Governor } from "./Governor" export { Governor } from "./Governor"

View File

@@ -7,6 +7,7 @@ import {
ClearCallbacksParams, ClearCallbacksParams,
ClearServiceInterfacesParams, ClearServiceInterfacesParams,
GetActionInputParams, GetActionInputParams,
GetStatusParams,
GetStoreParams, GetStoreParams,
RequestActionParams, RequestActionParams,
RunActionParams, RunActionParams,
@@ -89,6 +90,7 @@ describe("startosTypeValidation ", () => {
mount: {} as MountParams, mount: {} as MountParams,
checkDependencies: {} as CheckDependenciesParam, checkDependencies: {} as CheckDependenciesParam,
getDependencies: undefined, getDependencies: undefined,
getStatus: {} as WithCallback<GetStatusParams>,
setMainStatus: {} as SetMainStatus, setMainStatus: {} as SetMainStatus,
}) })
}) })

View File

@@ -134,6 +134,7 @@ export class StartSdk<Manifest extends T.SDKManifest, Store> {
getDataVersion: (effects, ...args) => effects.getDataVersion(...args), getDataVersion: (effects, ...args) => effects.getDataVersion(...args),
shutdown: (effects, ...args) => effects.shutdown(...args), shutdown: (effects, ...args) => effects.shutdown(...args),
getDependencies: (effects, ...args) => effects.getDependencies(...args), getDependencies: (effects, ...args) => effects.getDependencies(...args),
getStatus: (effects, ...args) => effects.getStatus(...args),
} }
return { return {
@@ -387,8 +388,8 @@ export class StartSdk<Manifest extends T.SDKManifest, Store> {
algorithm?: T.Algorithm, algorithm?: T.Algorithm,
) => new GetSslCertificate(effects, hostnames, algorithm), ) => new GetSslCertificate(effects, hostnames, algorithm),
HealthCheck: { HealthCheck: {
of(o: HealthCheckParams) { of(effects: T.Effects, o: Omit<HealthCheckParams, "effects">) {
return healthCheck(o) return healthCheck({ effects, ...o })
}, },
}, },
healthCheck: { healthCheck: {
@@ -636,12 +637,12 @@ export class StartSdk<Manifest extends T.SDKManifest, Store> {
) => InputSpec.of<Spec, Store>(spec), ) => InputSpec.of<Spec, Store>(spec),
}, },
Daemons: { Daemons: {
of(options: { of(
effects: Effects effects: Effects,
started: (onTerm: () => PromiseLike<void>) => PromiseLike<null> started: (onTerm: () => PromiseLike<void>) => PromiseLike<null>,
healthReceipts: HealthReceipt[] healthReceipts: HealthReceipt[],
}) { ) {
return Daemons.of<Manifest>(options) return Daemons.of<Manifest>({ effects, started, healthReceipts })
}, },
}, },
List: { List: {

View File

@@ -15,18 +15,14 @@ import { VersionGraph } from "../version/VersionGraph"
*/ */
export function setupManifest< export function setupManifest<
Id extends string, Id extends string,
Dependencies extends Record<string, unknown>,
VolumesTypes extends VolumeId, VolumesTypes extends VolumeId,
AssetTypes extends VolumeId, AssetTypes extends VolumeId,
ImagesTypes extends ImageId,
Manifest extends { Manifest extends {
dependencies: Dependencies
id: Id id: Id
assets: AssetTypes[] assets: AssetTypes[]
images: Record<ImagesTypes, SDKImageInputSpec>
volumes: VolumesTypes[] volumes: VolumesTypes[]
}, } & SDKManifest,
>(manifest: SDKManifest & Manifest): SDKManifest & Manifest { >(manifest: Manifest): Manifest {
return manifest return manifest
} }

View File

@@ -86,7 +86,7 @@ export class FileHelper<A> {
/** /**
* Accepts structured data and overwrites the existing file on disk. * Accepts structured data and overwrites the existing file on disk.
*/ */
async write(data: A): Promise<null> { private async writeFile(data: A): Promise<null> {
const parent = previousPath.exec(this.path) const parent = previousPath.exec(this.path)
if (parent) { if (parent) {
await fs.mkdir(parent[1], { recursive: true }) await fs.mkdir(parent[1], { recursive: true })
@@ -153,13 +153,27 @@ export class FileHelper<A> {
} }
/** /**
* Accepts structured data and performs a merge with the existing file on disk. * Accepts full structured data and performs a merge with the existing file on disk if it exists.
*/ */
async merge(data: A) { async write(data: A) {
const fileData = (await this.readOnce().catch(() => ({}))) || {} const fileData = (await this.readOnce()) || {}
const mergeData = merge({}, fileData, data) const mergeData = merge({}, fileData, data)
return await this.write(mergeData) return await this.writeFile(mergeData)
} }
/**
* Accepts partial structured data and performs a merge with the existing file on disk.
*/
async merge(data: Partial<A>) {
const fileData =
(await this.readOnce()) ||
(() => {
throw new Error(`${this.path}: does not exist`)
})()
const mergeData = merge({}, fileData, data)
return await this.writeFile(mergeData)
}
/** /**
* Create a File Helper for an arbitrary file type. * Create a File Helper for an arbitrary file type.
* *

484
web/package-lock.json generated
View File

@@ -21,20 +21,20 @@
"@angular/service-worker": "^14.2.2", "@angular/service-worker": "^14.2.2",
"@ionic/angular": "^6.1.15", "@ionic/angular": "^6.1.15",
"@materia-ui/ngx-monaco-editor": "^6.0.0", "@materia-ui/ngx-monaco-editor": "^6.0.0",
"@ng-web-apis/common": "^3.0.6", "@ng-web-apis/common": "^3.2.3",
"@ng-web-apis/mutation-observer": "^3.2.1", "@ng-web-apis/mutation-observer": "^3.2.3",
"@ng-web-apis/resize-observer": "^3.2.1", "@ng-web-apis/resize-observer": "^3.2.3",
"@noble/curves": "^1.4.0", "@noble/curves": "^1.4.0",
"@noble/hashes": "^1.4.0", "@noble/hashes": "^1.4.0",
"@start9labs/argon2": "^0.2.2", "@start9labs/argon2": "^0.2.2",
"@start9labs/emver": "^0.1.5", "@start9labs/emver": "^0.1.5",
"@start9labs/start-sdk": "file:../sdk/baseDist", "@start9labs/start-sdk": "file:../sdk/baseDist",
"@taiga-ui/addon-charts": "3.86.0", "@taiga-ui/addon-charts": "3.96.0",
"@taiga-ui/cdk": "3.86.0", "@taiga-ui/cdk": "3.96.0",
"@taiga-ui/core": "3.86.0", "@taiga-ui/core": "3.96.0",
"@taiga-ui/experimental": "3.86.0", "@taiga-ui/experimental": "3.96.0",
"@taiga-ui/icons": "3.86.0", "@taiga-ui/icons": "3.96.0",
"@taiga-ui/kit": "3.86.0", "@taiga-ui/kit": "3.96.0",
"@tinkoff/ng-dompurify": "4.0.0", "@tinkoff/ng-dompurify": "4.0.0",
"@tinkoff/ng-event-plugins": "3.2.0", "@tinkoff/ng-event-plugins": "3.2.0",
"angular-svg-round-progressbar": "^9.0.0", "angular-svg-round-progressbar": "^9.0.0",
@@ -3761,10 +3761,11 @@
} }
}, },
"node_modules/@jridgewell/sourcemap-codec": { "node_modules/@jridgewell/sourcemap-codec": {
"version": "1.4.15", "version": "1.5.0",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
"integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
"dev": true "devOptional": true,
"license": "MIT"
}, },
"node_modules/@jridgewell/trace-mapping": { "node_modules/@jridgewell/trace-mapping": {
"version": "0.3.25", "version": "0.3.25",
@@ -3786,6 +3787,7 @@
"version": "1.9.0", "version": "1.9.0",
"resolved": "https://registry.npmjs.org/@maskito/angular/-/angular-1.9.0.tgz", "resolved": "https://registry.npmjs.org/@maskito/angular/-/angular-1.9.0.tgz",
"integrity": "sha512-Wa/9nM9Nv0oieVZ6yxQNXfDRA4obFDR15xO16o1GKF8i9W1IdQQn+tuMRjkmx6HhJDN9+x3k8OTJ1f80BIrhjA==", "integrity": "sha512-Wa/9nM9Nv0oieVZ6yxQNXfDRA4obFDR15xO16o1GKF8i9W1IdQQn+tuMRjkmx6HhJDN9+x3k8OTJ1f80BIrhjA==",
"license": "Apache-2.0",
"dependencies": { "dependencies": {
"tslib": "2.6.2" "tslib": "2.6.2"
}, },
@@ -3800,17 +3802,20 @@
"node_modules/@maskito/angular/node_modules/tslib": { "node_modules/@maskito/angular/node_modules/tslib": {
"version": "2.6.2", "version": "2.6.2",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==",
"license": "0BSD"
}, },
"node_modules/@maskito/core": { "node_modules/@maskito/core": {
"version": "1.9.0", "version": "1.9.0",
"resolved": "https://registry.npmjs.org/@maskito/core/-/core-1.9.0.tgz", "resolved": "https://registry.npmjs.org/@maskito/core/-/core-1.9.0.tgz",
"integrity": "sha512-WQIUrwkdIUg6PzAb4Apa0RjTPHB0EqZLc9/7kWCKVIixhkITRFXFg2BhiDVSRv0mIKVlAEJcOvvjHK5T3UaIig==" "integrity": "sha512-WQIUrwkdIUg6PzAb4Apa0RjTPHB0EqZLc9/7kWCKVIixhkITRFXFg2BhiDVSRv0mIKVlAEJcOvvjHK5T3UaIig==",
"license": "Apache-2.0"
}, },
"node_modules/@maskito/kit": { "node_modules/@maskito/kit": {
"version": "1.9.0", "version": "1.9.0",
"resolved": "https://registry.npmjs.org/@maskito/kit/-/kit-1.9.0.tgz", "resolved": "https://registry.npmjs.org/@maskito/kit/-/kit-1.9.0.tgz",
"integrity": "sha512-LNNgOJ0tAfrPoPehvoP+ZyYF9giOYL02sOMKyDC3IcqDNA8BAU0PARmS7TNsVEBpvSuJhU6xVt40nxJaONgUdw==", "integrity": "sha512-LNNgOJ0tAfrPoPehvoP+ZyYF9giOYL02sOMKyDC3IcqDNA8BAU0PARmS7TNsVEBpvSuJhU6xVt40nxJaONgUdw==",
"license": "Apache-2.0",
"peerDependencies": { "peerDependencies": {
"@maskito/core": "^1.9.0" "@maskito/core": "^1.9.0"
} }
@@ -3828,9 +3833,10 @@
} }
}, },
"node_modules/@ng-web-apis/common": { "node_modules/@ng-web-apis/common": {
"version": "3.0.6", "version": "3.2.3",
"resolved": "https://registry.npmjs.org/@ng-web-apis/common/-/common-3.0.6.tgz", "resolved": "https://registry.npmjs.org/@ng-web-apis/common/-/common-3.2.3.tgz",
"integrity": "sha512-ral+lzGpFS3aOCFB5DcHOI4lZhhp8GH4BnjSbngH2Xk8J0FKYdxRzvcPQVy7hS+TPUu0tW9uFVp6cC7odu3iyQ==", "integrity": "sha512-1ts2FkLRw6dE/uTuYFMf9VTbLJ9CS8dpfIXTpxFsPArs13mEuz0Yvpe0rl0tMAhfNoeN4e7V8wVSyqDNgfzgmw==",
"license": "Apache-2.0",
"dependencies": { "dependencies": {
"tslib": "^2.2.0" "tslib": "^2.2.0"
}, },
@@ -3841,9 +3847,10 @@
} }
}, },
"node_modules/@ng-web-apis/intersection-observer": { "node_modules/@ng-web-apis/intersection-observer": {
"version": "3.2.0", "version": "3.2.3",
"resolved": "https://registry.npmjs.org/@ng-web-apis/intersection-observer/-/intersection-observer-3.2.0.tgz", "resolved": "https://registry.npmjs.org/@ng-web-apis/intersection-observer/-/intersection-observer-3.2.3.tgz",
"integrity": "sha512-EhwqEZJFKR9pz55TWp82qyWTXdg8TZeMP6bUw26bVHz8CTkgrpzaXdtxurMTvJ/+gwuFy4JSJLjBeV9nfZ/SXA==", "integrity": "sha512-0yp+rr6ZEyF2vz4zYlMZ1GNtTHQziKajCurqAycZkSXVUdon7MhfiY/PiTr8xklTr40DjrF4anXV7oUAaA0szQ==",
"license": "Apache-2.0",
"dependencies": { "dependencies": {
"tslib": "^2.2.0" "tslib": "^2.2.0"
}, },
@@ -3853,9 +3860,10 @@
} }
}, },
"node_modules/@ng-web-apis/mutation-observer": { "node_modules/@ng-web-apis/mutation-observer": {
"version": "3.2.1", "version": "3.2.3",
"resolved": "https://registry.npmjs.org/@ng-web-apis/mutation-observer/-/mutation-observer-3.2.1.tgz", "resolved": "https://registry.npmjs.org/@ng-web-apis/mutation-observer/-/mutation-observer-3.2.3.tgz",
"integrity": "sha512-a7krkMx0e9cfnutClwDylWjbTQVRHUP3oUik/nBvUdKlk/Q4anNww9aIKJ64VgiXR+1ZF8OmHGl0+XUzN6xP9Q==", "integrity": "sha512-iFwxut1cw94lTXnloDMBRanqNTvEjbnigWkTowlPH3QY16ysTKuC51JeonRuARW4K3bbDGbXiLUYYZWKQaDfKw==",
"license": "Apache-2.0",
"dependencies": { "dependencies": {
"tslib": "^2.2.0" "tslib": "^2.2.0"
}, },
@@ -3865,9 +3873,10 @@
} }
}, },
"node_modules/@ng-web-apis/resize-observer": { "node_modules/@ng-web-apis/resize-observer": {
"version": "3.2.1", "version": "3.2.3",
"resolved": "https://registry.npmjs.org/@ng-web-apis/resize-observer/-/resize-observer-3.2.1.tgz", "resolved": "https://registry.npmjs.org/@ng-web-apis/resize-observer/-/resize-observer-3.2.3.tgz",
"integrity": "sha512-r1YaZUo6DIDeR+4/C/pM4Ar0eTQBxjK0FUhYYJ512EnN8RqAn8d3a0wM8ZYunucwDICwW1sx4IIV6PZ2G77xsg==", "integrity": "sha512-x3KxBZSragzdQlkbY9tiHY0lVlkOFD7Y34rzXdBJ7PTnIvlq43X/tN31Mmb3R0Np4vsarWqnhO6Y42ljudsWdA==",
"license": "Apache-2.0",
"dependencies": { "dependencies": {
"tslib": "^2.2.0" "tslib": "^2.2.0"
}, },
@@ -4161,60 +4170,63 @@
} }
}, },
"node_modules/@taiga-ui/addon-charts": { "node_modules/@taiga-ui/addon-charts": {
"version": "3.86.0", "version": "3.96.0",
"resolved": "https://registry.npmjs.org/@taiga-ui/addon-charts/-/addon-charts-3.86.0.tgz", "resolved": "https://registry.npmjs.org/@taiga-ui/addon-charts/-/addon-charts-3.96.0.tgz",
"integrity": "sha512-Du/85qqaj8hpFSI6hPuFeIhtE93Z6WSkYZLt0gvnsaCb2qSAg8D4oHSogrtF1rsWGGoM+fvXjD7UEUw9GzFIPg==", "integrity": "sha512-vU8fZhwdg+sWOPJNnIrEtuuVkoFjQKeMhvk4f68oHBXUa0XUESS+qNeAfstvow6xnAZJrhxYtMoDuH/cgC7kNg==",
"license": "Apache-2.0",
"dependencies": { "dependencies": {
"tslib": "^2.6.2" "tslib": ">=2.7.0"
}, },
"peerDependencies": { "peerDependencies": {
"@angular/common": ">=12.0.0", "@angular/common": ">=12.0.0",
"@angular/core": ">=12.0.0", "@angular/core": ">=12.0.0",
"@ng-web-apis/common": "^3.0.6", "@ng-web-apis/common": ">=3.2.3 <4",
"@taiga-ui/cdk": "^3.86.0", "@taiga-ui/cdk": ">=3.96.0 <4",
"@taiga-ui/core": "^3.86.0", "@taiga-ui/core": ">=3.96.0 <4",
"@tinkoff/ng-polymorpheus": "^4.3.0" "@tinkoff/ng-polymorpheus": ">=4.3.0"
} }
}, },
"node_modules/@taiga-ui/addon-commerce": { "node_modules/@taiga-ui/addon-commerce": {
"version": "3.86.0", "version": "3.96.0",
"resolved": "https://registry.npmjs.org/@taiga-ui/addon-commerce/-/addon-commerce-3.86.0.tgz", "resolved": "https://registry.npmjs.org/@taiga-ui/addon-commerce/-/addon-commerce-3.96.0.tgz",
"integrity": "sha512-8QSB490ckI4jnU+1sQ3x8os2GVE162hbvzPVYIZ0TruoeXl076dAz6PT2WRaFwjcaCAIGsuaQgQ4Cv02NjkiYQ==", "integrity": "sha512-Y1MACB6KrQVnNjgeKQrNfbz51jMXbU7j83sL28+6q8DS9LNv4DVcv/r/UvK2VZ1PhESkBU85NJAIHf5iy9GN4g==",
"license": "Apache-2.0",
"peer": true, "peer": true,
"dependencies": { "dependencies": {
"tslib": "^2.6.2" "tslib": ">=2.7.0"
}, },
"peerDependencies": { "peerDependencies": {
"@angular/common": ">=12.0.0", "@angular/common": ">=12.0.0",
"@angular/core": ">=12.0.0", "@angular/core": ">=12.0.0",
"@angular/forms": ">=12.0.0", "@angular/forms": ">=12.0.0",
"@maskito/angular": "^1.9.0", "@maskito/angular": ">=1.9.0 <2",
"@maskito/core": "^1.9.0", "@maskito/core": ">=1.9.0 <2",
"@maskito/kit": "^1.9.0", "@maskito/kit": ">=1.9.0 <2",
"@ng-web-apis/common": "^3.0.6", "@ng-web-apis/common": ">=3.2.3 <4",
"@taiga-ui/cdk": "^3.86.0", "@taiga-ui/cdk": ">=3.96.0 <4",
"@taiga-ui/core": "^3.86.0", "@taiga-ui/core": ">=3.96.0 <4",
"@taiga-ui/i18n": "^3.86.0", "@taiga-ui/i18n": ">=3.96.0 <4",
"@taiga-ui/kit": "^3.86.0", "@taiga-ui/kit": ">=3.96.0 <4",
"@tinkoff/ng-polymorpheus": "^4.3.0", "@tinkoff/ng-polymorpheus": ">=4.3.0",
"rxjs": ">=6.0.0" "rxjs": ">=6.0.0"
} }
}, },
"node_modules/@taiga-ui/cdk": { "node_modules/@taiga-ui/cdk": {
"version": "3.86.0", "version": "3.96.0",
"resolved": "https://registry.npmjs.org/@taiga-ui/cdk/-/cdk-3.86.0.tgz", "resolved": "https://registry.npmjs.org/@taiga-ui/cdk/-/cdk-3.96.0.tgz",
"integrity": "sha512-aVbnW01Oh0Er1sHKVGHP8W05mOSKxjSzFE3Qx4iF4T6KW7Rlz9HZoNx5ADMg0TATYChtWh9Kwjo8I4LSVj2ZUw==", "integrity": "sha512-y1T4+Olhys370ePT8SvZpMlOConDG6bLxjo6jOvFI6D6w0nEgqRxxFDBcdoHxgMWJZdAg7lRLEtN9dHEwKaABA==",
"license": "Apache-2.0",
"dependencies": { "dependencies": {
"@ng-web-apis/common": "3.0.6", "@ng-web-apis/common": "^3.2.3",
"@ng-web-apis/mutation-observer": "3.1.0", "@ng-web-apis/mutation-observer": "^3.2.3",
"@ng-web-apis/resize-observer": "3.0.6", "@ng-web-apis/resize-observer": "^3.2.3",
"@tinkoff/ng-event-plugins": "3.2.0", "@tinkoff/ng-event-plugins": "^3.2.0",
"@tinkoff/ng-polymorpheus": "4.3.0", "@tinkoff/ng-polymorpheus": "^4.3.0",
"tslib": "2.6.2" "tslib": "^2.7.0"
}, },
"optionalDependencies": { "optionalDependencies": {
"ng-morph": "4.0.5", "ng-morph": "^4.8.2",
"parse5": "6.0.1" "parse5": "^6.0.1"
}, },
"peerDependencies": { "peerDependencies": {
"@angular/animations": ">=12.0.0", "@angular/animations": ">=12.0.0",
@@ -4224,42 +4236,166 @@
"rxjs": ">=6.0.0" "rxjs": ">=6.0.0"
} }
}, },
"node_modules/@taiga-ui/cdk/node_modules/@ng-web-apis/mutation-observer": { "node_modules/@taiga-ui/cdk/node_modules/@angular-devkit/core": {
"version": "3.1.0", "version": "18.2.9",
"resolved": "https://registry.npmjs.org/@ng-web-apis/mutation-observer/-/mutation-observer-3.1.0.tgz", "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-18.2.9.tgz",
"integrity": "sha512-MFN0TLLBMFJJPpXkGFe9ChRCSOKvMHZRRtBq5jHWS7tv5/CtdUkqW5CU7RC9KTzZjGeMzYe0cXO4JRkjL5aZ9g==", "integrity": "sha512-bsVt//5E0ua7FZfO0dCF/qGGY6KQD34/bNGyRu5B6HedimpdU2/0PGDptksU5v3yKEc9gNw0xC6mT0UsY/R9pA==",
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": { "dependencies": {
"tslib": "^2.2.0" "ajv": "8.17.1",
"ajv-formats": "3.0.1",
"jsonc-parser": "3.3.1",
"picomatch": "4.0.2",
"rxjs": "7.8.1",
"source-map": "0.7.4"
},
"engines": {
"node": "^18.19.1 || ^20.11.1 || >=22.0.0",
"npm": "^6.11.0 || ^7.5.6 || >=8.0.0",
"yarn": ">= 1.13.0"
}, },
"peerDependencies": { "peerDependencies": {
"@angular/core": ">=12.0.0", "chokidar": "^3.5.2"
"@ng-web-apis/common": ">=2.0.0" },
"peerDependenciesMeta": {
"chokidar": {
"optional": true
}
} }
}, },
"node_modules/@taiga-ui/cdk/node_modules/@ng-web-apis/resize-observer": { "node_modules/@taiga-ui/cdk/node_modules/@angular-devkit/schematics": {
"version": "3.0.6", "version": "18.2.9",
"resolved": "https://registry.npmjs.org/@ng-web-apis/resize-observer/-/resize-observer-3.0.6.tgz", "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-18.2.9.tgz",
"integrity": "sha512-QdGYdEdC0AzFonLfNOnyYyeCwnvK9jlskoeefvJN3Yyvds3ivBrrTjpeDOdiLsQpCPBp9/673imgq7355vkQow==", "integrity": "sha512-aIY5/IomDOINGCtFYi77uo0acDpdQNNCighfBBUGEBNMQ1eE3oGNGpLAH/qWeuxJndgmxrdKsvws9DdT46kLig==",
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": { "dependencies": {
"tslib": "^2.2.0" "@angular-devkit/core": "18.2.9",
"jsonc-parser": "3.3.1",
"magic-string": "0.30.11",
"ora": "5.4.1",
"rxjs": "7.8.1"
},
"engines": {
"node": "^18.19.1 || ^20.11.1 || >=22.0.0",
"npm": "^6.11.0 || ^7.5.6 || >=8.0.0",
"yarn": ">= 1.13.0"
}
},
"node_modules/@taiga-ui/cdk/node_modules/ajv": {
"version": "8.17.1",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
"integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
"fast-deep-equal": "^3.1.3",
"fast-uri": "^3.0.1",
"json-schema-traverse": "^1.0.0",
"require-from-string": "^2.0.2"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/epoberezkin"
}
},
"node_modules/@taiga-ui/cdk/node_modules/ajv-formats": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz",
"integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==",
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
"ajv": "^8.0.0"
}, },
"peerDependencies": { "peerDependencies": {
"@angular/core": ">=12.0.0", "ajv": "^8.0.0"
"@ng-web-apis/common": ">=2.0.0" },
"peerDependenciesMeta": {
"ajv": {
"optional": true
}
} }
}, },
"node_modules/@taiga-ui/cdk/node_modules/tslib": { "node_modules/@taiga-ui/cdk/node_modules/jsonc-parser": {
"version": "2.6.2", "version": "3.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz",
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==",
"license": "MIT",
"optional": true
},
"node_modules/@taiga-ui/cdk/node_modules/magic-string": {
"version": "0.30.11",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.11.tgz",
"integrity": "sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==",
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.5.0"
}
},
"node_modules/@taiga-ui/cdk/node_modules/minimatch": {
"version": "10.0.1",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz",
"integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==",
"license": "ISC",
"optional": true,
"dependencies": {
"brace-expansion": "^2.0.1"
},
"engines": {
"node": "20 || >=22"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/@taiga-ui/cdk/node_modules/ng-morph": {
"version": "4.8.4",
"resolved": "https://registry.npmjs.org/ng-morph/-/ng-morph-4.8.4.tgz",
"integrity": "sha512-XwL53wCOhyaAxvoekN74ONbWUK30huzp+GpZYyC01RfaG2AX9l7YlC1mGG/l7Rx7YXtFAk85VFnNJqn2e46K8g==",
"license": "Apache-2.0",
"optional": true,
"dependencies": {
"jsonc-parser": "3.3.1",
"minimatch": "10.0.1",
"multimatch": "5.0.0",
"ts-morph": "23.0.0"
},
"peerDependencies": {
"@angular-devkit/core": ">=16.0.0",
"@angular-devkit/schematics": ">=16.0.0",
"tslib": "^2.7.0"
}
},
"node_modules/@taiga-ui/cdk/node_modules/picomatch": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
"integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
"license": "MIT",
"optional": true,
"peer": true,
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/jonschlinkert"
}
}, },
"node_modules/@taiga-ui/core": { "node_modules/@taiga-ui/core": {
"version": "3.86.0", "version": "3.96.0",
"resolved": "https://registry.npmjs.org/@taiga-ui/core/-/core-3.86.0.tgz", "resolved": "https://registry.npmjs.org/@taiga-ui/core/-/core-3.96.0.tgz",
"integrity": "sha512-diQKOnPtDDfxPOMk6wLRq8nyDVfNSPSNy+1TeyqzUgOvJ6XAjfaBXGsL3iuR7AN8+sz/b3rJmBce+vdw6FjMLQ==", "integrity": "sha512-0w2Jpesb2oM+5aMTfSKFzzYdfPDHXq0fhE6TN4Eutc9LO4Lyh6Hg0KPfoHmw8Tj6wg4KxBcdeAj/opNehWwrVw==",
"license": "Apache-2.0",
"dependencies": { "dependencies": {
"@taiga-ui/i18n": "^3.86.0", "@taiga-ui/i18n": "^3.96.0",
"tslib": "^2.6.2" "tslib": ">=2.7.0"
}, },
"peerDependencies": { "peerDependencies": {
"@angular/animations": ">=12.0.0", "@angular/animations": ">=12.0.0",
@@ -4268,81 +4404,85 @@
"@angular/forms": ">=12.0.0", "@angular/forms": ">=12.0.0",
"@angular/platform-browser": ">=12.0.0", "@angular/platform-browser": ">=12.0.0",
"@angular/router": ">=12.0.0", "@angular/router": ">=12.0.0",
"@ng-web-apis/common": "^3.0.6", "@ng-web-apis/common": ">=3.2.3 <4",
"@ng-web-apis/mutation-observer": "^3.1.0", "@ng-web-apis/mutation-observer": ">=3.2.3 <4",
"@taiga-ui/cdk": "^3.86.0", "@taiga-ui/cdk": ">=3.96.0 <4",
"@taiga-ui/i18n": "^3.86.0", "@taiga-ui/i18n": ">=3.96.0 <4",
"@tinkoff/ng-event-plugins": "^3.2.0", "@tinkoff/ng-event-plugins": ">=3.2.0 <4",
"@tinkoff/ng-polymorpheus": "^4.3.0", "@tinkoff/ng-polymorpheus": ">=4.3.0",
"rxjs": ">=6.0.0" "rxjs": ">=6.0.0"
} }
}, },
"node_modules/@taiga-ui/experimental": { "node_modules/@taiga-ui/experimental": {
"version": "3.86.0", "version": "3.96.0",
"resolved": "https://registry.npmjs.org/@taiga-ui/experimental/-/experimental-3.86.0.tgz", "resolved": "https://registry.npmjs.org/@taiga-ui/experimental/-/experimental-3.96.0.tgz",
"integrity": "sha512-ACjoRVeX5MgsNJsiu2ukliXLD2mfEWm8Vtmk78vqcnkyPUmy1ZWK4sG3p5ybFN8AdIMHkblVq0l+x2qAwr/+LQ==", "integrity": "sha512-AxEaYieouK3NzkGzOVTojnHBAd/eRw5D2sVAK+SQdBFdBjQiRGk/FKzZhOWpDOQOcIN+lhpDGpth3KV30+AgFQ==",
"license": "Apache-2.0",
"dependencies": { "dependencies": {
"tslib": "^2.6.2" "tslib": ">=2.7.0"
}, },
"peerDependencies": { "peerDependencies": {
"@angular/common": ">=12.0.0", "@angular/common": ">=12.0.0",
"@angular/core": ">=12.0.0", "@angular/core": ">=12.0.0",
"@taiga-ui/addon-commerce": "^3.86.0", "@taiga-ui/addon-commerce": ">=3.96.0 <4",
"@taiga-ui/cdk": "^3.86.0", "@taiga-ui/cdk": ">=3.96.0 <4",
"@taiga-ui/core": "^3.86.0", "@taiga-ui/core": ">=3.96.0 <4",
"@taiga-ui/kit": "^3.86.0", "@taiga-ui/kit": ">=3.96.0 <4",
"@tinkoff/ng-polymorpheus": "^4.3.0", "@tinkoff/ng-polymorpheus": ">=4.3.0",
"rxjs": ">=6.0.0" "rxjs": ">=6.0.0"
} }
}, },
"node_modules/@taiga-ui/i18n": { "node_modules/@taiga-ui/i18n": {
"version": "3.86.0", "version": "3.96.0",
"resolved": "https://registry.npmjs.org/@taiga-ui/i18n/-/i18n-3.86.0.tgz", "resolved": "https://registry.npmjs.org/@taiga-ui/i18n/-/i18n-3.96.0.tgz",
"integrity": "sha512-8zkNhMo/QtxZ2Zp6EP/nxo4SOLwaIrX+P3X/Wt+1cjFNZUYWWfdvfHLLdNviKFPVl4RAOxvkhDfza/wkrwv+iQ==", "integrity": "sha512-SGO89mRhmdD3BldQJiSqDCftEjjaOKXLJFFEZWBtrhelxKX5hWJ2lL0O+WzVAMegbQqHoT60HoHrWZIlSy9tVQ==",
"license": "Apache-2.0",
"dependencies": { "dependencies": {
"tslib": "^2.6.2" "tslib": ">=2.7.0"
}, },
"peerDependencies": { "peerDependencies": {
"@angular/core": ">=12.0.0", "@angular/core": ">=12.0.0",
"@ng-web-apis/common": "^3.0.6", "@ng-web-apis/common": ">=3.2.3 <4",
"rxjs": ">=6.0.0" "rxjs": ">=6.0.0"
} }
}, },
"node_modules/@taiga-ui/icons": { "node_modules/@taiga-ui/icons": {
"version": "3.86.0", "version": "3.96.0",
"resolved": "https://registry.npmjs.org/@taiga-ui/icons/-/icons-3.86.0.tgz", "resolved": "https://registry.npmjs.org/@taiga-ui/icons/-/icons-3.96.0.tgz",
"integrity": "sha512-jVBEbvE/r9JG+knmXMTn/l/js3JjYi8nSGbrLCryJZZoS2izRnQARN2txABieUJm8H463CoF0rcdXlHKRuA4Ew==", "integrity": "sha512-bBuX8RGAqr2+9TRbTA4RAmq3v4pnE9ObDwoq/5CrUtE3Wr7idcl7hgfW3yeyhpdOdJJMGfbTauPBONLz2uFRCQ==",
"license": "Apache-2.0",
"dependencies": { "dependencies": {
"tslib": "^2.6.2" "tslib": ">=2.7.0"
}, },
"peerDependencies": { "peerDependencies": {
"@taiga-ui/cdk": "^3.86.0" "@taiga-ui/cdk": ">=3.96.0 <4"
} }
}, },
"node_modules/@taiga-ui/kit": { "node_modules/@taiga-ui/kit": {
"version": "3.86.0", "version": "3.96.0",
"resolved": "https://registry.npmjs.org/@taiga-ui/kit/-/kit-3.86.0.tgz", "resolved": "https://registry.npmjs.org/@taiga-ui/kit/-/kit-3.96.0.tgz",
"integrity": "sha512-naAy4pyhCaQ9+vWxqSMjbV+9KwnMxT5ybrw+MAJgMn2evzRq0FjqzyFZFog7oiRbRvgVdoWPQfBNKaaLhJcpsw==", "integrity": "sha512-gHn0AZU1kiNZU2T/LnnxLGkHC3/XNroBWCGmhxupAmL/JcsmOXsl3L8aK1rZhjS4QgkmgaC5ueVWNwdXINRnXw==",
"license": "Apache-2.0",
"dependencies": { "dependencies": {
"@maskito/angular": "1.9.0", "@maskito/angular": "^1.9.0",
"@maskito/core": "1.9.0", "@maskito/core": "^1.9.0",
"@maskito/kit": "1.9.0", "@maskito/kit": "^1.9.0",
"@ng-web-apis/intersection-observer": "3.2.0", "@ng-web-apis/intersection-observer": "^3.2.3",
"text-mask-core": "5.1.2", "text-mask-core": "^5.1.2",
"tslib": "^2.6.2" "tslib": ">=2.7.0"
}, },
"peerDependencies": { "peerDependencies": {
"@angular/common": ">=12.0.0", "@angular/common": ">=12.0.0",
"@angular/core": ">=12.0.0", "@angular/core": ">=12.0.0",
"@angular/forms": ">=12.0.0", "@angular/forms": ">=12.0.0",
"@angular/router": ">=12.0.0", "@angular/router": ">=12.0.0",
"@ng-web-apis/common": "3.0.6", "@ng-web-apis/common": ">=3.2.3 <4",
"@ng-web-apis/mutation-observer": "^3.1.0", "@ng-web-apis/mutation-observer": ">=3.2.3 <4",
"@ng-web-apis/resize-observer": "^3.0.6", "@ng-web-apis/resize-observer": ">=3.2.3 <4",
"@taiga-ui/cdk": "^3.86.0", "@taiga-ui/cdk": ">=3.96.0 <4",
"@taiga-ui/core": "^3.86.0", "@taiga-ui/core": ">=3.96.0 <4",
"@taiga-ui/i18n": "^3.86.0", "@taiga-ui/i18n": ">=3.96.0 <4",
"@tinkoff/ng-polymorpheus": "^4.3.0", "@tinkoff/ng-polymorpheus": ">=4.3.0",
"rxjs": ">=6.0.0" "rxjs": ">=6.0.0"
} }
}, },
@@ -4400,13 +4540,14 @@
} }
}, },
"node_modules/@ts-morph/common": { "node_modules/@ts-morph/common": {
"version": "0.22.0", "version": "0.24.0",
"resolved": "https://registry.npmjs.org/@ts-morph/common/-/common-0.22.0.tgz", "resolved": "https://registry.npmjs.org/@ts-morph/common/-/common-0.24.0.tgz",
"integrity": "sha512-HqNBuV/oIlMKdkLshXd1zKBqNQCsuPEsgQOkfFQ/eUKjRlwndXW1AjN9LVkBEIukm00gGXSRmfkl0Wv5VXLnlw==", "integrity": "sha512-c1xMmNHWpNselmpIqursHeOHHBTIsJLbB+NuovbTTRCNiTLEr/U9dbJ8qy0jd/O2x5pc3seWuOUN5R2IoOTp8A==",
"license": "MIT",
"optional": true, "optional": true,
"dependencies": { "dependencies": {
"fast-glob": "^3.3.2", "fast-glob": "^3.3.2",
"minimatch": "^9.0.3", "minimatch": "^9.0.4",
"mkdirp": "^3.0.1", "mkdirp": "^3.0.1",
"path-browserify": "^1.0.1" "path-browserify": "^1.0.1"
} }
@@ -4415,6 +4556,7 @@
"version": "9.0.5", "version": "9.0.5",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
"license": "ISC",
"optional": true, "optional": true,
"dependencies": { "dependencies": {
"brace-expansion": "^2.0.1" "brace-expansion": "^2.0.1"
@@ -4430,6 +4572,7 @@
"version": "3.0.1", "version": "3.0.1",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz",
"integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==",
"license": "MIT",
"optional": true, "optional": true,
"bin": { "bin": {
"mkdirp": "dist/cjs/src/bin.js" "mkdirp": "dist/cjs/src/bin.js"
@@ -4613,6 +4756,7 @@
"version": "3.0.5", "version": "3.0.5",
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz",
"integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==",
"license": "MIT",
"optional": true "optional": true
}, },
"node_modules/@types/mustache": { "node_modules/@types/mustache": {
@@ -5237,6 +5381,7 @@
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz", "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz",
"integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==", "integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==",
"license": "MIT",
"optional": true, "optional": true,
"engines": { "engines": {
"node": ">=8" "node": ">=8"
@@ -5252,6 +5397,7 @@
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
"integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
"license": "MIT",
"optional": true, "optional": true,
"engines": { "engines": {
"node": ">=8" "node": ">=8"
@@ -5261,6 +5407,7 @@
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz",
"integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==",
"license": "MIT",
"optional": true, "optional": true,
"engines": { "engines": {
"node": ">=8" "node": ">=8"
@@ -6088,9 +6235,10 @@
} }
}, },
"node_modules/code-block-writer": { "node_modules/code-block-writer": {
"version": "12.0.0", "version": "13.0.3",
"resolved": "https://registry.npmjs.org/code-block-writer/-/code-block-writer-12.0.0.tgz", "resolved": "https://registry.npmjs.org/code-block-writer/-/code-block-writer-13.0.3.tgz",
"integrity": "sha512-q4dMFMlXtKR3XNBHyMHt/3pwYNA69EDk00lloMOaaUMKPUXBw6lpXtbu3MMVG6/uOihGnRDOlkyqsONEUj60+w==", "integrity": "sha512-Oofo0pq3IKnsFtuHqSF7TqBfr71aeyZDVJ0HpmqB7FBM2qEigL0iPONSCZSO9pE9dZTAxANe5XHG9Uy0YMv8cg==",
"license": "MIT",
"optional": true "optional": true
}, },
"node_modules/color-convert": { "node_modules/color-convert": {
@@ -7868,6 +8016,14 @@
"integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==",
"dev": true "dev": true
}, },
"node_modules/fast-uri": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.3.tgz",
"integrity": "sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==",
"license": "BSD-3-Clause",
"optional": true,
"peer": true
},
"node_modules/fastq": { "node_modules/fastq": {
"version": "1.17.1", "version": "1.17.1",
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz",
@@ -10651,6 +10807,7 @@
"version": "5.0.0", "version": "5.0.0",
"resolved": "https://registry.npmjs.org/multimatch/-/multimatch-5.0.0.tgz", "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-5.0.0.tgz",
"integrity": "sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA==", "integrity": "sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA==",
"license": "MIT",
"optional": true, "optional": true,
"dependencies": { "dependencies": {
"@types/minimatch": "^3.0.3", "@types/minimatch": "^3.0.3",
@@ -10670,6 +10827,7 @@
"version": "1.1.11", "version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"license": "MIT",
"optional": true, "optional": true,
"dependencies": { "dependencies": {
"balanced-match": "^1.0.0", "balanced-match": "^1.0.0",
@@ -10680,6 +10838,7 @@
"version": "3.1.2", "version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"license": "ISC",
"optional": true, "optional": true,
"dependencies": { "dependencies": {
"brace-expansion": "^1.1.7" "brace-expansion": "^1.1.7"
@@ -10781,50 +10940,6 @@
"node": ">= 0.4.0" "node": ">= 0.4.0"
} }
}, },
"node_modules/ng-morph": {
"version": "4.0.5",
"resolved": "https://registry.npmjs.org/ng-morph/-/ng-morph-4.0.5.tgz",
"integrity": "sha512-5tnlb5WrGKeo2E7VRcV7ZHhScyNgliYqpbXqt103kynmfj6Ic8kzhJAhHu9iLkF1yRnKv2kyCE+O7UGZx5RraQ==",
"optional": true,
"dependencies": {
"jsonc-parser": "3.2.0",
"minimatch": "9.0.3",
"multimatch": "5.0.0",
"ts-morph": "21.0.1",
"tslib": "2.6.2"
},
"peerDependencies": {
"@angular-devkit/core": ">=11.0.0",
"@angular-devkit/schematics": ">=11.0.0"
}
},
"node_modules/ng-morph/node_modules/jsonc-parser": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz",
"integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==",
"optional": true
},
"node_modules/ng-morph/node_modules/minimatch": {
"version": "9.0.3",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz",
"integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
"optional": true,
"dependencies": {
"brace-expansion": "^2.0.1"
},
"engines": {
"node": ">=16 || 14 >=14.17"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/ng-morph/node_modules/tslib": {
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==",
"optional": true
},
"node_modules/ng-packagr": { "node_modules/ng-packagr": {
"version": "14.2.2", "version": "14.2.2",
"resolved": "https://registry.npmjs.org/ng-packagr/-/ng-packagr-14.2.2.tgz", "resolved": "https://registry.npmjs.org/ng-packagr/-/ng-packagr-14.2.2.tgz",
@@ -14794,7 +14909,8 @@
"node_modules/text-mask-core": { "node_modules/text-mask-core": {
"version": "5.1.2", "version": "5.1.2",
"resolved": "https://registry.npmjs.org/text-mask-core/-/text-mask-core-5.1.2.tgz", "resolved": "https://registry.npmjs.org/text-mask-core/-/text-mask-core-5.1.2.tgz",
"integrity": "sha512-VfkCMdmRRZqXgQZFlDMiavm3hzsMzBM23CxHZsaeAYg66ZhXCNJWrFmnJwNy8KF9f74YvAUAuQenxsMCfuvhUw==" "integrity": "sha512-VfkCMdmRRZqXgQZFlDMiavm3hzsMzBM23CxHZsaeAYg66ZhXCNJWrFmnJwNy8KF9f74YvAUAuQenxsMCfuvhUw==",
"license": "Unlicense"
}, },
"node_modules/text-table": { "node_modules/text-table": {
"version": "0.2.0", "version": "0.2.0",
@@ -14880,13 +14996,14 @@
"integrity": "sha512-UFYaKgfqlg9FROK7bdpYqFwG1CJvP4kOJdjXuWoqxo9jCmANoDw1GxkSCpJgoTeIiSTaTH5Qr1klSspb8c+ydg==" "integrity": "sha512-UFYaKgfqlg9FROK7bdpYqFwG1CJvP4kOJdjXuWoqxo9jCmANoDw1GxkSCpJgoTeIiSTaTH5Qr1klSspb8c+ydg=="
}, },
"node_modules/ts-morph": { "node_modules/ts-morph": {
"version": "21.0.1", "version": "23.0.0",
"resolved": "https://registry.npmjs.org/ts-morph/-/ts-morph-21.0.1.tgz", "resolved": "https://registry.npmjs.org/ts-morph/-/ts-morph-23.0.0.tgz",
"integrity": "sha512-dbDtVdEAncKctzrVZ+Nr7kHpHkv+0JDJb2MjjpBaj8bFeCkePU9rHfMklmhuLFnpeq/EJZk2IhStY6NzqgjOkg==", "integrity": "sha512-FcvFx7a9E8TUe6T3ShihXJLiJOiqyafzFKUO4aqIHDUCIvADdGNShcbc2W5PMr3LerXRv7mafvFZ9lRENxJmug==",
"license": "MIT",
"optional": true, "optional": true,
"dependencies": { "dependencies": {
"@ts-morph/common": "~0.22.0", "@ts-morph/common": "~0.24.0",
"code-block-writer": "^12.0.0" "code-block-writer": "^13.0.1"
} }
}, },
"node_modules/ts-node": { "node_modules/ts-node": {
@@ -14933,9 +15050,10 @@
} }
}, },
"node_modules/tslib": { "node_modules/tslib": {
"version": "2.6.3", "version": "2.8.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.0.tgz",
"integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" "integrity": "sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==",
"license": "0BSD"
}, },
"node_modules/tslint": { "node_modules/tslint": {
"version": "6.1.3", "version": "6.1.3",

View File

@@ -43,20 +43,20 @@
"@angular/service-worker": "^14.2.2", "@angular/service-worker": "^14.2.2",
"@ionic/angular": "^6.1.15", "@ionic/angular": "^6.1.15",
"@materia-ui/ngx-monaco-editor": "^6.0.0", "@materia-ui/ngx-monaco-editor": "^6.0.0",
"@ng-web-apis/common": "^3.0.6", "@ng-web-apis/common": "^3.2.3",
"@ng-web-apis/mutation-observer": "^3.2.1", "@ng-web-apis/mutation-observer": "^3.2.3",
"@ng-web-apis/resize-observer": "^3.2.1", "@ng-web-apis/resize-observer": "^3.2.3",
"@noble/curves": "^1.4.0", "@noble/curves": "^1.4.0",
"@noble/hashes": "^1.4.0", "@noble/hashes": "^1.4.0",
"@start9labs/argon2": "^0.2.2", "@start9labs/argon2": "^0.2.2",
"@start9labs/emver": "^0.1.5", "@start9labs/emver": "^0.1.5",
"@start9labs/start-sdk": "file:../sdk/baseDist", "@start9labs/start-sdk": "file:../sdk/baseDist",
"@taiga-ui/addon-charts": "3.86.0", "@taiga-ui/addon-charts": "3.96.0",
"@taiga-ui/cdk": "3.86.0", "@taiga-ui/cdk": "3.96.0",
"@taiga-ui/core": "3.86.0", "@taiga-ui/core": "3.96.0",
"@taiga-ui/experimental": "3.86.0", "@taiga-ui/experimental": "3.96.0",
"@taiga-ui/icons": "3.86.0", "@taiga-ui/icons": "3.96.0",
"@taiga-ui/kit": "3.86.0", "@taiga-ui/kit": "3.96.0",
"@tinkoff/ng-dompurify": "4.0.0", "@tinkoff/ng-dompurify": "4.0.0",
"@tinkoff/ng-event-plugins": "3.2.0", "@tinkoff/ng-event-plugins": "3.2.0",
"angular-svg-round-progressbar": "^9.0.0", "angular-svg-round-progressbar": "^9.0.0",

View File

@@ -1,23 +1,23 @@
import { CommonModule } from '@angular/common' import { CommonModule } from '@angular/common'
import { ChangeDetectionStrategy, Component, Input } from '@angular/core' import { ChangeDetectionStrategy, Component, Input } from '@angular/core'
import { T } from '@start9labs/start-sdk'
import { TuiFadeModule, TuiTitleModule } from '@taiga-ui/experimental' import { TuiFadeModule, TuiTitleModule } from '@taiga-ui/experimental'
import { TuiAccordionModule } from '@taiga-ui/kit' import { TuiAccordionModule } from '@taiga-ui/kit'
import { ActionSuccessItemComponent } from './action-success-item.component' import { ActionSuccessMemberComponent } from './action-success-member.component'
import { GroupResult } from './types'
@Component({ @Component({
standalone: true, standalone: true,
selector: 'app-action-success-group', selector: 'app-action-success-group',
template: ` template: `
<p *ngFor="let item of value?.value"> <p *ngFor="let member of group.value">
<app-action-success-item <app-action-success-member
*ngIf="isSingle(item)" *ngIf="member.type === 'single'"
[value]="item" [member]="member"
></app-action-success-item> ></app-action-success-member>
<tui-accordion-item *ngIf="!isSingle(item)" size="s"> <tui-accordion-item *ngIf="member.type === 'group'">
<div tuiFade>{{ item.name }}</div> <div tuiFade>{{ member.name }}</div>
<ng-template tuiAccordionItemContent> <ng-template tuiAccordionItemContent>
<app-action-success-group [value]="item"></app-action-success-group> <app-action-success-group [group]="member"></app-action-success-group>
</ng-template> </ng-template>
</tui-accordion-item> </tui-accordion-item>
</p> </p>
@@ -37,18 +37,12 @@ import { ActionSuccessItemComponent } from './action-success-item.component'
imports: [ imports: [
CommonModule, CommonModule,
TuiTitleModule, TuiTitleModule,
ActionSuccessItemComponent, ActionSuccessMemberComponent,
TuiAccordionModule, TuiAccordionModule,
TuiFadeModule, TuiFadeModule,
], ],
}) })
export class ActionSuccessGroupComponent { export class ActionSuccessGroupComponent {
@Input() @Input()
value?: T.ActionResultV1 & { type: 'object' } group!: GroupResult
isSingle(
value: T.ActionResultV1,
): value is T.ActionResultV1 & { type: 'string' } {
return value.type === 'string'
}
} }

View File

@@ -9,41 +9,38 @@ import {
ViewChild, ViewChild,
} from '@angular/core' } from '@angular/core'
import { FormsModule } from '@angular/forms' import { FormsModule } from '@angular/forms'
import { T } from '@start9labs/start-sdk'
import { import {
TuiDialogService, TuiDialogService,
TuiLabelModule,
TuiTextfieldComponent, TuiTextfieldComponent,
TuiTextfieldControllerModule, TuiTextfieldControllerModule,
} from '@taiga-ui/core' } from '@taiga-ui/core'
import { TuiButtonModule } from '@taiga-ui/experimental' import { TuiButtonModule, TuiTitleModule } from '@taiga-ui/experimental'
import { TuiInputModule } from '@taiga-ui/kit' import { TuiInputModule } from '@taiga-ui/kit'
import { QrCodeModule } from 'ng-qrcode' import { QrCodeModule } from 'ng-qrcode'
import { ActionSuccessGroupComponent } from './action-success-group.component' import { T } from '@start9labs/start-sdk'
@Component({ @Component({
standalone: true, standalone: true,
selector: 'app-action-success-item', selector: 'app-action-success-member',
template: ` template: `
<p *ngIf="!parent" class="qr"> <tui-input
<ng-container *ngTemplateOutlet="qr"></ng-container> [readOnly]="true"
</p> [ngModel]="member.value"
<label [tuiLabel]="value.description"> [tuiTextfieldCustomContent]="actions"
<tui-input >
[readOnly]="true" {{ member.name }}
[ngModel]="value.value" <input
[tuiTextfieldCustomContent]="actions" tuiTextfield
> [style.border-inline-end-width.rem]="border"
<input [type]="member.masked && masked ? 'password' : 'text'"
tuiTextfield />
[style.border-inline-end-width.rem]="border" </tui-input>
[type]="value.masked && masked ? 'password' : 'text'" <label *ngIf="member.description" [style.padding-top.rem]="0.25" tuiTitle>
/> <span tuiSubtitle [style.opacity]="0.8">{{ member.description }}</span>
</tui-input>
</label> </label>
<ng-template #actions> <ng-template #actions>
<button <button
*ngIf="value.masked" *ngIf="member.masked"
tuiIconButton tuiIconButton
appearance="icon" appearance="icon"
size="s" size="s"
@@ -56,7 +53,7 @@ import { ActionSuccessGroupComponent } from './action-success-group.component'
Reveal/Hide Reveal/Hide
</button> </button>
<button <button
*ngIf="value.copyable" *ngIf="member.copyable"
tuiIconButton tuiIconButton
appearance="icon" appearance="icon"
size="s" size="s"
@@ -69,7 +66,7 @@ import { ActionSuccessGroupComponent } from './action-success-group.component'
Copy Copy
</button> </button>
<button <button
*ngIf="value.qr && parent" *ngIf="member.qr"
tuiIconButton tuiIconButton
appearance="icon" appearance="icon"
size="s" size="s"
@@ -84,12 +81,12 @@ import { ActionSuccessGroupComponent } from './action-success-group.component'
</ng-template> </ng-template>
<ng-template #qr> <ng-template #qr>
<qr-code <qr-code
[value]="value.value" [value]="member.value"
[style.filter]="value.masked && masked ? 'blur(0.5rem)' : null" [style.filter]="member.masked && masked ? 'blur(0.5rem)' : null"
size="350" size="350"
></qr-code> ></qr-code>
<button <button
*ngIf="value.masked && masked" *ngIf="member.masked && masked"
tuiIconButton tuiIconButton
class="reveal" class="reveal"
iconLeft="tuiIconEye" iconLeft="tuiIconEye"
@@ -122,37 +119,25 @@ import { ActionSuccessGroupComponent } from './action-success-group.component'
TuiTextfieldControllerModule, TuiTextfieldControllerModule,
TuiButtonModule, TuiButtonModule,
QrCodeModule, QrCodeModule,
TuiLabelModule, TuiTitleModule,
], ],
}) })
export class ActionSuccessItemComponent { export class ActionSuccessMemberComponent {
@ViewChild(TuiTextfieldComponent, { read: ElementRef }) @ViewChild(TuiTextfieldComponent, { read: ElementRef })
private readonly input!: ElementRef<HTMLInputElement> private readonly input!: ElementRef<HTMLInputElement>
private readonly dialogs = inject(TuiDialogService) private readonly dialogs = inject(TuiDialogService)
readonly parent = inject(ActionSuccessGroupComponent, {
optional: true,
})
@Input() @Input()
value!: T.ActionResultV1 & { type: 'string' } member!: T.ActionResultMember & { type: 'single' }
masked = true masked = true
get border(): number { get border(): number {
let border = 0 let border = 0
if (this.value.masked) { if (this.member.masked) border += 2
border += 2 if (this.member.copyable) border += 2
} if (this.member.qr) border += 2
if (this.value.copyable) {
border += 2
}
if (this.value.qr && this.parent) {
border += 2
}
return border return border
} }
@@ -160,7 +145,7 @@ export class ActionSuccessItemComponent {
show(template: TemplateRef<any>) { show(template: TemplateRef<any>) {
const masked = this.masked const masked = this.masked
this.masked = this.value.masked this.masked = this.member.masked
this.dialogs this.dialogs
.open(template, { label: 'Scan this QR', size: 's' }) .open(template, { label: 'Scan this QR', size: 's' })
.subscribe({ .subscribe({
@@ -179,6 +164,6 @@ export class ActionSuccessItemComponent {
el.focus() el.focus()
el.select() el.select()
el.ownerDocument.execCommand('copy') el.ownerDocument.execCommand('copy')
el.type = this.masked && this.value.masked ? 'password' : 'text' el.type = this.masked && this.member.masked ? 'password' : 'text'
} }
} }

View File

@@ -0,0 +1,145 @@
import { CommonModule } from '@angular/common'
import {
ChangeDetectionStrategy,
Component,
ElementRef,
inject,
Input,
TemplateRef,
ViewChild,
} from '@angular/core'
import { FormsModule } from '@angular/forms'
import {
TuiDialogService,
TuiLabelModule,
TuiTextfieldComponent,
TuiTextfieldControllerModule,
} from '@taiga-ui/core'
import { TuiButtonModule } from '@taiga-ui/experimental'
import { TuiInputModule } from '@taiga-ui/kit'
import { QrCodeModule } from 'ng-qrcode'
import { SingleResult } from './types'
@Component({
standalone: true,
selector: 'app-action-success-single',
template: `
<p class="qr">
<ng-container *ngTemplateOutlet="qr"></ng-container>
</p>
<tui-input
[readOnly]="true"
[ngModel]="single.value"
[tuiTextfieldLabelOutside]="true"
[tuiTextfieldCustomContent]="actions"
>
<input
tuiTextfield
[style.border-inline-end-width.rem]="border"
[type]="single.masked && masked ? 'password' : 'text'"
/>
</tui-input>
<ng-template #actions>
<button
*ngIf="single.masked"
tuiIconButton
appearance="icon"
size="s"
type="button"
tabindex="-1"
[iconLeft]="masked ? 'tuiIconEye' : 'tuiIconEyeOff'"
[style.pointer-events]="'auto'"
(click)="masked = !masked"
>
Reveal/Hide
</button>
<button
*ngIf="single.copyable"
tuiIconButton
appearance="icon"
size="s"
type="button"
tabindex="-1"
iconLeft="tuiIconCopy"
[style.pointer-events]="'auto'"
(click)="copy()"
>
Copy
</button>
</ng-template>
<ng-template #qr>
<qr-code
[value]="single.value"
[style.filter]="single.masked && masked ? 'blur(0.5rem)' : null"
size="350"
></qr-code>
<button
*ngIf="single.masked && masked"
tuiIconButton
class="reveal"
iconLeft="tuiIconEye"
[style.border-radius.%]="100"
(click)="masked = false"
>
Reveal
</button>
</ng-template>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
styles: [
`
@import '@taiga-ui/core/styles/taiga-ui-local';
.reveal {
@include center-all();
}
.qr {
position: relative;
text-align: center;
}
`,
],
imports: [
CommonModule,
FormsModule,
TuiInputModule,
TuiTextfieldControllerModule,
TuiButtonModule,
QrCodeModule,
TuiLabelModule,
],
})
export class ActionSuccessSingleComponent {
@ViewChild(TuiTextfieldComponent, { read: ElementRef })
private readonly input!: ElementRef<HTMLInputElement>
private readonly dialogs = inject(TuiDialogService)
@Input()
single!: SingleResult
masked = true
get border(): number {
let border = 0
if (this.single.masked) border += 2
if (this.single.copyable) border += 2
return border
}
copy() {
const el = this.input.nativeElement
if (!el) {
return
}
el.type = 'text'
el.focus()
el.select()
el.ownerDocument.execCommand('copy')
el.type = this.masked && this.single.masked ? 'password' : 'text'
}
}

View File

@@ -1,36 +1,36 @@
import { CommonModule } from '@angular/common' import { CommonModule } from '@angular/common'
import { Component, inject } from '@angular/core' import { Component, inject } from '@angular/core'
import { TuiDialogContext, TuiTextfieldControllerModule } from '@taiga-ui/core' import { TuiDialogContext } from '@taiga-ui/core'
import { POLYMORPHEUS_CONTEXT } from '@tinkoff/ng-polymorpheus' import { POLYMORPHEUS_CONTEXT } from '@tinkoff/ng-polymorpheus'
import { RR } from 'src/app/services/api/api.types'
import { ActionSuccessGroupComponent } from './action-success-group.component' import { ActionSuccessGroupComponent } from './action-success-group.component'
import { ActionSuccessItemComponent } from './action-success-item.component' import { ActionSuccessSingleComponent } from './action-success-single.component'
import { ActionResponseWithResult } from './types'
@Component({ @Component({
standalone: true, standalone: true,
template: ` template: `
<ng-container tuiTextfieldSize="m" [tuiTextfieldLabelOutside]="true"> <p *ngIf="data.message">{{ data.message }}</p>
<app-action-success-item <app-action-success-single
*ngIf="item" *ngIf="single"
[value]="item" [single]="single"
></app-action-success-item> ></app-action-success-single>
<app-action-success-group <app-action-success-group
*ngIf="group" *ngIf="group"
[value]="group" [group]="group"
></app-action-success-group> ></app-action-success-group>
</ng-container>
`, `,
imports: [ imports: [
CommonModule, CommonModule,
ActionSuccessGroupComponent, ActionSuccessGroupComponent,
ActionSuccessItemComponent, ActionSuccessSingleComponent,
TuiTextfieldControllerModule,
], ],
}) })
export class ActionSuccessPage { export class ActionSuccessPage {
readonly data = readonly data =
inject<TuiDialogContext<void, RR.ActionRes>>(POLYMORPHEUS_CONTEXT).data inject<TuiDialogContext<void, ActionResponseWithResult>>(
POLYMORPHEUS_CONTEXT,
).data
readonly item = this.data?.type === 'string' ? this.data : null readonly single = this.data.result.type === 'single' ? this.data.result : null
readonly group = this.data?.type === 'object' ? this.data : null readonly group = this.data.result.type === 'group' ? this.data.result : null
} }

View File

@@ -0,0 +1,7 @@
import { RR } from 'src/app/services/api/api.types'
type ActionResponse = NonNullable<RR.ActionRes>
type ActionResult = NonNullable<ActionResponse['result']>
export type ActionResponseWithResult = ActionResponse & { result: ActionResult }
export type SingleResult = ActionResult & { type: 'single' }
export type GroupResult = ActionResult & { type: 'group' }

View File

@@ -118,13 +118,17 @@ export class ActionService {
input: input || null, input: input || null,
}) })
if (res) { if (!res) return true
if (res.result) {
this.dialogs this.dialogs
.open(new PolymorpheusComponent(ActionSuccessPage), { .open(new PolymorpheusComponent(ActionSuccessPage), {
label: res.name, label: res.title,
data: res, data: res,
}) })
.subscribe() .subscribe()
} else if (res.message) {
this.dialogs.open(res.message, { label: res.title }).subscribe()
} }
return true // needed to dismiss original modal/alert return true // needed to dismiss original modal/alert
} catch (e: any) { } catch (e: any) {

View File

@@ -1049,77 +1049,91 @@ export module Mock {
}, },
} }
export const ActionRes: RR.ActionRes = { export const ActionResMessage: RR.ActionRes = {
version: '1', version: '1',
type: 'string', title: 'New Password',
name: 'New Password', message:
description: 'Action was run successfully and smoothly and fully and all is good on the western front.',
'Action was run successfully Action was run successfully Action was run successfully Action was run successfully Action was run successfully', result: null,
copyable: true,
qr: true,
masked: true,
value: 'iwejdoiewdhbew',
} }
export const ActionProperties: RR.ActionRes = { export const ActionResSingle: RR.ActionRes = {
version: '1', version: '1',
type: 'object', title: 'New Password',
name: 'Properties', message:
value: [ 'Action was run successfully and smoothly and fully and all is good on the western front.',
{ result: {
type: 'string', type: 'single',
name: 'LND Connect', copyable: true,
description: 'This is some information about the thing.', qr: true,
copyable: true, masked: true,
qr: true, value: 'iwejdoiewdhbew',
masked: true, },
value: }
'lndconnect://udlyfq2mxa4355pt7cqlrdipnvk2tsl4jtsdw7zaeekenufwcev2wlad.onion:10009?cert=MIICJTCCAcugAwIBAgIRAOyq85fqAiA3U3xOnwhH678wCgYIKoZIzj0EAwIwODEfMB0GAkUEChMWbG5kIGF1dG9nZW5lcmF0ZWQgY2VydDEVMBMGA1UEAxMMNTc0OTkwMzIyYzZlMB4XDTIwMTAyNjA3MzEyN1oXDTIxMTIyMTA3MzEyN1owODEfMB0GA1UEChMWbG5kIGF1dG9nZW5lcmF0ZWQgY2VydDEVMBMGA1UEAxMMNTc0OTkwMzIyYzZlMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEKqfhAMMZdY-eFnU5P4bGrQTSx0lo7m8u4V0yYkzUM6jlql_u31_mU2ovLTj56wnZApkEjoPl6fL2yasZA2wiy6OBtTCBsjAOBgNVHQ8BAf8EBAMCAqQwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDwYDVR0TAQH_BAUwAwEB_zAdBgNVHQ4EFgQUYQ9uIO6spltnVCx4rLFL5BvBF9IwWwYDVR0RBFQwUoIMNTc0OTkwMzIyYzZlgglsb2NhbGhvc3SCBHVuaXiCCnVuaXhwYWNrZXSCB2J1ZmNvbm6HBH8AAAGHEAAAAAAAAAAAAAAAAAAAAAGHBKwSAAswCgYIKoZIzj0EAwIDSAAwRQIgVZH2Z2KlyAVY2Q2aIQl0nsvN-OEN49wreFwiBqlxNj4CIQD5_JbpuBFJuf81I5J0FQPtXY-4RppWOPZBb-y6-rkIUQ&macaroon=AgEDbG5kAusBAwoQuA8OUMeQ8Fr2h-f65OdXdRIBMBoWCgdhZGRyZXNzEgRyZWFkEgV3cml0ZRoTCgRpbmZvEgRyZWFkEgV3cml0ZRoXCghpbnZvaWNlcxIEcmVhZBIFd3JpdGUaFAoIbWFjYXJvb24SCGdlbmVyYXRlGhYKB21lc3NhZ2USBHJlYWQSBXdyaXRlGhcKCG9mZmNoYWluEgRyZWFkEgV3cml0ZRoWCgdvbmNoYWluEgRyZWFkEgV3cml0ZRoUCgVwZWVycxIEcmVhZBIFd3JpdGUaGAoGc2lnbmVyEghnZW5lcmF0ZRIEcmVhZAAABiCYsRUoUWuAHAiCSLbBR7b_qULDSl64R8LIU2aqNIyQfA',
}, export const ActionResGroup: RR.ActionRes = {
{ version: '1',
type: 'object', title: 'Properties',
name: 'Nested Stuff', message:
description: 'This is a nested thing metric', 'Successfully retrieved properties. Here is a bunch of useful information about this service.',
value: [ result: {
{ type: 'group',
type: 'string', value: [
name: 'Last Name', {
description: 'The last name of the user', type: 'single',
copyable: true, name: 'LND Connect',
qr: true, description: 'This is some information about the thing.',
masked: false, copyable: true,
value: 'Hill', qr: true,
}, masked: true,
{ value:
type: 'string', 'lndconnect://udlyfq2mxa4355pt7cqlrdipnvk2tsl4jtsdw7zaeekenufwcev2wlad.onion:10009?cert=MIICJTCCAcugAwIBAgIRAOyq85fqAiA3U3xOnwhH678wCgYIKoZIzj0EAwIwODEfMB0GAkUEChMWbG5kIGF1dG9nZW5lcmF0ZWQgY2VydDEVMBMGA1UEAxMMNTc0OTkwMzIyYzZlMB4XDTIwMTAyNjA3MzEyN1oXDTIxMTIyMTA3MzEyN1owODEfMB0GA1UEChMWbG5kIGF1dG9nZW5lcmF0ZWQgY2VydDEVMBMGA1UEAxMMNTc0OTkwMzIyYzZlMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEKqfhAMMZdY-eFnU5P4bGrQTSx0lo7m8u4V0yYkzUM6jlql_u31_mU2ovLTj56wnZApkEjoPl6fL2yasZA2wiy6OBtTCBsjAOBgNVHQ8BAf8EBAMCAqQwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDwYDVR0TAQH_BAUwAwEB_zAdBgNVHQ4EFgQUYQ9uIO6spltnVCx4rLFL5BvBF9IwWwYDVR0RBFQwUoIMNTc0OTkwMzIyYzZlgglsb2NhbGhvc3SCBHVuaXiCCnVuaXhwYWNrZXSCB2J1ZmNvbm6HBH8AAAGHEAAAAAAAAAAAAAAAAAAAAAGHBKwSAAswCgYIKoZIzj0EAwIDSAAwRQIgVZH2Z2KlyAVY2Q2aIQl0nsvN-OEN49wreFwiBqlxNj4CIQD5_JbpuBFJuf81I5J0FQPtXY-4RppWOPZBb-y6-rkIUQ&macaroon=AgEDbG5kAusBAwoQuA8OUMeQ8Fr2h-f65OdXdRIBMBoWCgdhZGRyZXNzEgRyZWFkEgV3cml0ZRoTCgRpbmZvEgRyZWFkEgV3cml0ZRoXCghpbnZvaWNlcxIEcmVhZBIFd3JpdGUaFAoIbWFjYXJvb24SCGdlbmVyYXRlGhYKB21lc3NhZ2USBHJlYWQSBXdyaXRlGhcKCG9mZmNoYWluEgRyZWFkEgV3cml0ZRoWCgdvbmNoYWluEgRyZWFkEgV3cml0ZRoUCgVwZWVycxIEcmVhZBIFd3JpdGUaGAoGc2lnbmVyEghnZW5lcmF0ZRIEcmVhZAAABiCYsRUoUWuAHAiCSLbBR7b_qULDSl64R8LIU2aqNIyQfA',
name: 'Age', },
description: 'The age of the user', {
copyable: false, type: 'group',
qr: false, name: 'Nested Stuff',
masked: false, description: 'This is a nested thing metric',
value: '35', value: [
}, {
{ type: 'single',
type: 'string', name: 'Last Name',
name: 'Password', description: 'The last name of the user',
description: 'A secret password', copyable: true,
copyable: true, qr: true,
qr: false, masked: false,
masked: true, value: 'Hill',
value: 'password123', },
}, {
], type: 'single',
}, name: 'Age',
{ description: 'The age of the user',
type: 'string', copyable: false,
name: 'Another Value', qr: false,
description: 'Some more information about the service.', masked: false,
copyable: false, value: '35',
qr: true, },
masked: false, {
value: 'https://guessagain.com', type: 'single',
}, name: 'Password',
], description: 'A secret password',
copyable: true,
qr: false,
masked: true,
value: 'password123',
},
],
},
{
type: 'single',
name: 'Another Value',
description: 'Some more information about the service.',
copyable: false,
qr: true,
masked: false,
value: 'https://guessagain.com',
},
],
},
} }
export const getActionInputSpec = async (): Promise<IST.InputSpec> => export const getActionInputSpec = async (): Promise<IST.InputSpec> =>

View File

@@ -784,7 +784,9 @@ export class MockApiService extends ApiService {
await pauseFor(2000) await pauseFor(2000)
if (params.actionId === 'properties') { if (params.actionId === 'properties') {
return Mock.ActionProperties // return Mock.ActionResGroup
return Mock.ActionResMessage
// return Mock.ActionResSingle
} else if (params.actionId === 'config') { } else if (params.actionId === 'config') {
const patch: RemoveOperation[] = [ const patch: RemoveOperation[] = [
{ {
@@ -795,7 +797,8 @@ export class MockApiService extends ApiService {
this.mockRevision(patch) this.mockRevision(patch)
return null return null
} else { } else {
return Mock.ActionRes return Mock.ActionResMessage
// return Mock.ActionResSingle
} }
} }