mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-26 10:21:52 +00:00
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:
@@ -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> {
|
||||
return rpcRound("set-main-status", o) as ReturnType<
|
||||
T.Effects["setHealth"]
|
||||
|
||||
@@ -245,10 +245,10 @@ const matchProperties = object({
|
||||
function convertProperties(
|
||||
name: string,
|
||||
value: PropertiesValue,
|
||||
): T.ActionResultV1 {
|
||||
): T.ActionResultMember {
|
||||
if (value.type === "string") {
|
||||
return {
|
||||
type: "string",
|
||||
type: "single",
|
||||
name,
|
||||
description: value.description,
|
||||
copyable: value.copyable || false,
|
||||
@@ -258,9 +258,9 @@ function convertProperties(
|
||||
}
|
||||
}
|
||||
return {
|
||||
type: "object",
|
||||
type: "group",
|
||||
name,
|
||||
description: value.description || undefined,
|
||||
description: value.description,
|
||||
value: Object.entries(value.value).map(([name, value]) =>
|
||||
convertProperties(name, value),
|
||||
),
|
||||
@@ -459,13 +459,14 @@ export class SystemForEmbassy implements System {
|
||||
} else if (actionId === "properties") {
|
||||
return {
|
||||
version: "1",
|
||||
type: "object",
|
||||
name: "Properties",
|
||||
description:
|
||||
"Runtime information, credentials, and other values of interest",
|
||||
value: Object.entries(await this.properties(effects, timeoutMs)).map(
|
||||
([name, value]) => convertProperties(name, value),
|
||||
),
|
||||
title: "Properties",
|
||||
message: null,
|
||||
result: {
|
||||
type: "group",
|
||||
value: Object.entries(await this.properties(effects, timeoutMs)).map(
|
||||
([name, value]) => convertProperties(name, value),
|
||||
),
|
||||
},
|
||||
}
|
||||
} else {
|
||||
return this.action(effects, actionId, input, timeoutMs)
|
||||
@@ -814,13 +815,13 @@ export class SystemForEmbassy implements System {
|
||||
const actionProcedure = this.manifest.actions?.[actionId]?.implementation
|
||||
const toActionResult = ({
|
||||
message,
|
||||
value = "",
|
||||
value,
|
||||
copyable,
|
||||
qr,
|
||||
}: U.ActionResult): T.ActionResult => ({
|
||||
version: "0",
|
||||
message,
|
||||
value,
|
||||
value: value ?? null,
|
||||
copyable,
|
||||
qr,
|
||||
})
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use std::collections::BTreeMap;
|
||||
use std::fmt;
|
||||
|
||||
use clap::{CommandFactory, FromArgMatches, Parser};
|
||||
@@ -6,7 +7,6 @@ use models::PackageId;
|
||||
use qrcode::QrCode;
|
||||
use rpc_toolkit::{from_fn_async, Context, HandlerExt, ParentHandler};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::BTreeMap;
|
||||
use tracing::instrument;
|
||||
use ts_rs::TS;
|
||||
|
||||
@@ -24,7 +24,7 @@ pub fn action_api<C: Context>() -> ParentHandler<C> {
|
||||
from_fn_async(get_action_input)
|
||||
.with_display_serializable()
|
||||
.with_about("Get action input spec")
|
||||
.with_call_remote::<CliContext>()
|
||||
.with_call_remote::<CliContext>(),
|
||||
)
|
||||
.subcommand(
|
||||
"run",
|
||||
@@ -37,7 +37,7 @@ pub fn action_api<C: Context>() -> ParentHandler<C> {
|
||||
Ok(())
|
||||
})
|
||||
.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)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[serde(rename_all_fields = "camelCase")]
|
||||
#[serde(tag = "type")]
|
||||
pub enum ActionResultV1 {
|
||||
String {
|
||||
name: String,
|
||||
pub enum ActionResultValue {
|
||||
Single {
|
||||
value: String,
|
||||
description: Option<String>,
|
||||
copyable: bool,
|
||||
qr: bool,
|
||||
masked: bool,
|
||||
},
|
||||
Object {
|
||||
name: String,
|
||||
value: Vec<ActionResultV1>,
|
||||
#[ts(optional)]
|
||||
description: Option<String>,
|
||||
Group {
|
||||
value: Vec<ActionResultMember>,
|
||||
},
|
||||
}
|
||||
impl ActionResultV1 {
|
||||
impl ActionResultValue {
|
||||
fn fmt_rec(&self, f: &mut fmt::Formatter<'_>, indent: usize) -> fmt::Result {
|
||||
match self {
|
||||
Self::String {
|
||||
name,
|
||||
value,
|
||||
description,
|
||||
qr,
|
||||
..
|
||||
} => {
|
||||
for i in 0..indent {
|
||||
Self::Single { value, qr, .. } => {
|
||||
for _ in 0..indent {
|
||||
write!(f, " ")?;
|
||||
}
|
||||
write!(f, "{name}")?;
|
||||
if let Some(description) = description {
|
||||
write!(f, ": {description}")?;
|
||||
}
|
||||
if !value.is_empty() {
|
||||
write!(f, ":\n")?;
|
||||
for i in 0..indent {
|
||||
write!(f, "{value}")?;
|
||||
if *qr {
|
||||
use qrcode::render::unicode;
|
||||
writeln!(f)?;
|
||||
for _ in 0..indent {
|
||||
write!(f, " ")?;
|
||||
}
|
||||
write!(f, "{value}")?;
|
||||
if *qr {
|
||||
use qrcode::render::unicode;
|
||||
write!(f, "\n")?;
|
||||
for i in 0..indent {
|
||||
write!(f, " ")?;
|
||||
}
|
||||
write!(
|
||||
f,
|
||||
"{}",
|
||||
QrCode::new(value.as_bytes())
|
||||
.unwrap()
|
||||
.render::<unicode::Dense1x2>()
|
||||
.build()
|
||||
)?;
|
||||
}
|
||||
write!(
|
||||
f,
|
||||
"{}",
|
||||
QrCode::new(value.as_bytes())
|
||||
.unwrap()
|
||||
.render::<unicode::Dense1x2>()
|
||||
.build()
|
||||
)?;
|
||||
}
|
||||
}
|
||||
Self::Object {
|
||||
name,
|
||||
value,
|
||||
description,
|
||||
} => {
|
||||
for i in 0..indent {
|
||||
write!(f, " ")?;
|
||||
}
|
||||
write!(f, "{name}")?;
|
||||
if let Some(description) = description {
|
||||
write!(f, ": {description}")?;
|
||||
}
|
||||
for value in value {
|
||||
write!(f, ":\n")?;
|
||||
for i in 0..indent {
|
||||
Self::Group { value } => {
|
||||
for ActionResultMember {
|
||||
name,
|
||||
description,
|
||||
value,
|
||||
} in value
|
||||
{
|
||||
for _ in 0..indent {
|
||||
write!(f, " ")?;
|
||||
}
|
||||
write!(f, "{name}")?;
|
||||
if let Some(description) = description {
|
||||
write!(f, ": {description}")?;
|
||||
}
|
||||
writeln!(f, ":")?;
|
||||
value.fmt_rec(f, indent + 1)?;
|
||||
}
|
||||
}
|
||||
@@ -207,7 +202,14 @@ impl ActionResultV1 {
|
||||
}
|
||||
impl fmt::Display for ActionResultV1 {
|
||||
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(())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ struct ServiceCallbackMap {
|
||||
(NonDetachingJoinHandle<()>, Vec<CallbackHandler>),
|
||||
>,
|
||||
get_store: BTreeMap<PackageId, BTreeMap<JsonPointer, Vec<CallbackHandler>>>,
|
||||
get_status: BTreeMap<PackageId, Vec<CallbackHandler>>,
|
||||
}
|
||||
|
||||
impl ServiceCallbacks {
|
||||
@@ -71,6 +72,10 @@ impl ServiceCallbacks {
|
||||
});
|
||||
!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);
|
||||
})
|
||||
}
|
||||
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(
|
||||
&self,
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
use std::str::FromStr;
|
||||
|
||||
use clap::builder::ValueParserFactory;
|
||||
use models::FromStrParser;
|
||||
use models::{FromStrParser, PackageId};
|
||||
|
||||
use crate::service::effects::prelude::*;
|
||||
use crate::service::rpc::CallbackId;
|
||||
use crate::status::MainStatus;
|
||||
|
||||
pub async fn restart(
|
||||
context: EffectContext,
|
||||
@@ -23,6 +25,46 @@ pub async fn shutdown(
|
||||
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)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export)]
|
||||
|
||||
@@ -50,6 +50,12 @@ pub fn handler<C: Context>() -> ParentHandler<C> {
|
||||
.no_display()
|
||||
.with_call_remote::<ContainerCliContext>(),
|
||||
)
|
||||
.subcommand(
|
||||
"get-status",
|
||||
from_fn_async(control::get_status)
|
||||
.no_display()
|
||||
.with_call_remote::<ContainerCliContext>(),
|
||||
)
|
||||
// dependency
|
||||
.subcommand(
|
||||
"set-dependencies",
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
use imbl::vector;
|
||||
|
||||
use super::start_stop::StartStop;
|
||||
use super::ServiceActorSeed;
|
||||
use crate::prelude::*;
|
||||
@@ -45,7 +47,8 @@ async fn service_actor_loop(
|
||||
let id = &seed.id;
|
||||
let kinds = current.borrow().kinds();
|
||||
if let Err(e) = async {
|
||||
seed.ctx
|
||||
let major_changes_state = seed
|
||||
.ctx
|
||||
.db
|
||||
.mutate(|d| {
|
||||
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,
|
||||
};
|
||||
let previous = i.as_status().de()?;
|
||||
i.as_status_mut().ser(&main_status)?;
|
||||
return Ok(previous
|
||||
.major_changes(&main_status)
|
||||
.then_some((previous, main_status)));
|
||||
}
|
||||
Ok(())
|
||||
Ok(None)
|
||||
})
|
||||
.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();
|
||||
|
||||
match kinds {
|
||||
|
||||
@@ -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 {
|
||||
MainStatus::BackingUp {
|
||||
on_complete: if self.running() {
|
||||
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
ServiceInterface,
|
||||
ActionRequest,
|
||||
RequestActionParams,
|
||||
MainStatus,
|
||||
} from "./osBindings"
|
||||
import { StorePath } from "./util/PathBuilder"
|
||||
import {
|
||||
@@ -61,6 +62,11 @@ export type Effects = {
|
||||
restart(): Promise<null>
|
||||
/** stop this service's main function */
|
||||
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 */
|
||||
setMainStatus(options: SetMainStatus): Promise<null>
|
||||
|
||||
|
||||
15
sdk/base/lib/osBindings/ActionResultMember.ts
Normal file
15
sdk/base/lib/osBindings/ActionResultMember.ts
Normal 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> }
|
||||
)
|
||||
@@ -1,18 +1,8 @@
|
||||
// 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 =
|
||||
| {
|
||||
type: "string"
|
||||
name: string
|
||||
value: string
|
||||
description: string | null
|
||||
copyable: boolean
|
||||
qr: boolean
|
||||
masked: boolean
|
||||
}
|
||||
| {
|
||||
type: "object"
|
||||
name: string
|
||||
value: Array<ActionResultV1>
|
||||
description?: string
|
||||
}
|
||||
export type ActionResultV1 = {
|
||||
title: string
|
||||
message: string | null
|
||||
result: ActionResultValue | null
|
||||
}
|
||||
|
||||
12
sdk/base/lib/osBindings/ActionResultValue.ts
Normal file
12
sdk/base/lib/osBindings/ActionResultValue.ts
Normal 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> }
|
||||
5
sdk/base/lib/osBindings/GetStatusParams.ts
Normal file
5
sdk/base/lib/osBindings/GetStatusParams.ts
Normal 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 }
|
||||
@@ -7,9 +7,11 @@ export { ActionRequestEntry } from "./ActionRequestEntry"
|
||||
export { ActionRequestInput } from "./ActionRequestInput"
|
||||
export { ActionRequestTrigger } from "./ActionRequestTrigger"
|
||||
export { ActionRequest } from "./ActionRequest"
|
||||
export { ActionResultMember } from "./ActionResultMember"
|
||||
export { ActionResult } from "./ActionResult"
|
||||
export { ActionResultV0 } from "./ActionResultV0"
|
||||
export { ActionResultV1 } from "./ActionResultV1"
|
||||
export { ActionResultValue } from "./ActionResultValue"
|
||||
export { ActionSeverity } from "./ActionSeverity"
|
||||
export { ActionVisibility } from "./ActionVisibility"
|
||||
export { AddAdminParams } from "./AddAdminParams"
|
||||
@@ -79,6 +81,7 @@ export { GetServiceInterfaceParams } from "./GetServiceInterfaceParams"
|
||||
export { GetServicePortForwardParams } from "./GetServicePortForwardParams"
|
||||
export { GetSslCertificateParams } from "./GetSslCertificateParams"
|
||||
export { GetSslKeyParams } from "./GetSslKeyParams"
|
||||
export { GetStatusParams } from "./GetStatusParams"
|
||||
export { GetStoreParams } from "./GetStoreParams"
|
||||
export { GetSystemSmtpParams } from "./GetSystemSmtpParams"
|
||||
export { Governor } from "./Governor"
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
ClearCallbacksParams,
|
||||
ClearServiceInterfacesParams,
|
||||
GetActionInputParams,
|
||||
GetStatusParams,
|
||||
GetStoreParams,
|
||||
RequestActionParams,
|
||||
RunActionParams,
|
||||
@@ -89,6 +90,7 @@ describe("startosTypeValidation ", () => {
|
||||
mount: {} as MountParams,
|
||||
checkDependencies: {} as CheckDependenciesParam,
|
||||
getDependencies: undefined,
|
||||
getStatus: {} as WithCallback<GetStatusParams>,
|
||||
setMainStatus: {} as SetMainStatus,
|
||||
})
|
||||
})
|
||||
|
||||
@@ -134,6 +134,7 @@ export class StartSdk<Manifest extends T.SDKManifest, Store> {
|
||||
getDataVersion: (effects, ...args) => effects.getDataVersion(...args),
|
||||
shutdown: (effects, ...args) => effects.shutdown(...args),
|
||||
getDependencies: (effects, ...args) => effects.getDependencies(...args),
|
||||
getStatus: (effects, ...args) => effects.getStatus(...args),
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -387,8 +388,8 @@ export class StartSdk<Manifest extends T.SDKManifest, Store> {
|
||||
algorithm?: T.Algorithm,
|
||||
) => new GetSslCertificate(effects, hostnames, algorithm),
|
||||
HealthCheck: {
|
||||
of(o: HealthCheckParams) {
|
||||
return healthCheck(o)
|
||||
of(effects: T.Effects, o: Omit<HealthCheckParams, "effects">) {
|
||||
return healthCheck({ effects, ...o })
|
||||
},
|
||||
},
|
||||
healthCheck: {
|
||||
@@ -636,12 +637,12 @@ export class StartSdk<Manifest extends T.SDKManifest, Store> {
|
||||
) => InputSpec.of<Spec, Store>(spec),
|
||||
},
|
||||
Daemons: {
|
||||
of(options: {
|
||||
effects: Effects
|
||||
started: (onTerm: () => PromiseLike<void>) => PromiseLike<null>
|
||||
healthReceipts: HealthReceipt[]
|
||||
}) {
|
||||
return Daemons.of<Manifest>(options)
|
||||
of(
|
||||
effects: Effects,
|
||||
started: (onTerm: () => PromiseLike<void>) => PromiseLike<null>,
|
||||
healthReceipts: HealthReceipt[],
|
||||
) {
|
||||
return Daemons.of<Manifest>({ effects, started, healthReceipts })
|
||||
},
|
||||
},
|
||||
List: {
|
||||
|
||||
@@ -15,18 +15,14 @@ import { VersionGraph } from "../version/VersionGraph"
|
||||
*/
|
||||
export function setupManifest<
|
||||
Id extends string,
|
||||
Dependencies extends Record<string, unknown>,
|
||||
VolumesTypes extends VolumeId,
|
||||
AssetTypes extends VolumeId,
|
||||
ImagesTypes extends ImageId,
|
||||
Manifest extends {
|
||||
dependencies: Dependencies
|
||||
id: Id
|
||||
assets: AssetTypes[]
|
||||
images: Record<ImagesTypes, SDKImageInputSpec>
|
||||
volumes: VolumesTypes[]
|
||||
},
|
||||
>(manifest: SDKManifest & Manifest): SDKManifest & Manifest {
|
||||
} & SDKManifest,
|
||||
>(manifest: Manifest): Manifest {
|
||||
return manifest
|
||||
}
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@ export class FileHelper<A> {
|
||||
/**
|
||||
* 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)
|
||||
if (parent) {
|
||||
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) {
|
||||
const fileData = (await this.readOnce().catch(() => ({}))) || {}
|
||||
async write(data: A) {
|
||||
const fileData = (await this.readOnce()) || {}
|
||||
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.
|
||||
*
|
||||
|
||||
484
web/package-lock.json
generated
484
web/package-lock.json
generated
@@ -21,20 +21,20 @@
|
||||
"@angular/service-worker": "^14.2.2",
|
||||
"@ionic/angular": "^6.1.15",
|
||||
"@materia-ui/ngx-monaco-editor": "^6.0.0",
|
||||
"@ng-web-apis/common": "^3.0.6",
|
||||
"@ng-web-apis/mutation-observer": "^3.2.1",
|
||||
"@ng-web-apis/resize-observer": "^3.2.1",
|
||||
"@ng-web-apis/common": "^3.2.3",
|
||||
"@ng-web-apis/mutation-observer": "^3.2.3",
|
||||
"@ng-web-apis/resize-observer": "^3.2.3",
|
||||
"@noble/curves": "^1.4.0",
|
||||
"@noble/hashes": "^1.4.0",
|
||||
"@start9labs/argon2": "^0.2.2",
|
||||
"@start9labs/emver": "^0.1.5",
|
||||
"@start9labs/start-sdk": "file:../sdk/baseDist",
|
||||
"@taiga-ui/addon-charts": "3.86.0",
|
||||
"@taiga-ui/cdk": "3.86.0",
|
||||
"@taiga-ui/core": "3.86.0",
|
||||
"@taiga-ui/experimental": "3.86.0",
|
||||
"@taiga-ui/icons": "3.86.0",
|
||||
"@taiga-ui/kit": "3.86.0",
|
||||
"@taiga-ui/addon-charts": "3.96.0",
|
||||
"@taiga-ui/cdk": "3.96.0",
|
||||
"@taiga-ui/core": "3.96.0",
|
||||
"@taiga-ui/experimental": "3.96.0",
|
||||
"@taiga-ui/icons": "3.96.0",
|
||||
"@taiga-ui/kit": "3.96.0",
|
||||
"@tinkoff/ng-dompurify": "4.0.0",
|
||||
"@tinkoff/ng-event-plugins": "3.2.0",
|
||||
"angular-svg-round-progressbar": "^9.0.0",
|
||||
@@ -3761,10 +3761,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/sourcemap-codec": {
|
||||
"version": "1.4.15",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
|
||||
"integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
|
||||
"dev": true
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
|
||||
"integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
|
||||
"devOptional": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@jridgewell/trace-mapping": {
|
||||
"version": "0.3.25",
|
||||
@@ -3786,6 +3787,7 @@
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@maskito/angular/-/angular-1.9.0.tgz",
|
||||
"integrity": "sha512-Wa/9nM9Nv0oieVZ6yxQNXfDRA4obFDR15xO16o1GKF8i9W1IdQQn+tuMRjkmx6HhJDN9+x3k8OTJ1f80BIrhjA==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"tslib": "2.6.2"
|
||||
},
|
||||
@@ -3800,17 +3802,20 @@
|
||||
"node_modules/@maskito/angular/node_modules/tslib": {
|
||||
"version": "2.6.2",
|
||||
"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": {
|
||||
"version": "1.9.0",
|
||||
"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": {
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@maskito/kit/-/kit-1.9.0.tgz",
|
||||
"integrity": "sha512-LNNgOJ0tAfrPoPehvoP+ZyYF9giOYL02sOMKyDC3IcqDNA8BAU0PARmS7TNsVEBpvSuJhU6xVt40nxJaONgUdw==",
|
||||
"license": "Apache-2.0",
|
||||
"peerDependencies": {
|
||||
"@maskito/core": "^1.9.0"
|
||||
}
|
||||
@@ -3828,9 +3833,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@ng-web-apis/common": {
|
||||
"version": "3.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@ng-web-apis/common/-/common-3.0.6.tgz",
|
||||
"integrity": "sha512-ral+lzGpFS3aOCFB5DcHOI4lZhhp8GH4BnjSbngH2Xk8J0FKYdxRzvcPQVy7hS+TPUu0tW9uFVp6cC7odu3iyQ==",
|
||||
"version": "3.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@ng-web-apis/common/-/common-3.2.3.tgz",
|
||||
"integrity": "sha512-1ts2FkLRw6dE/uTuYFMf9VTbLJ9CS8dpfIXTpxFsPArs13mEuz0Yvpe0rl0tMAhfNoeN4e7V8wVSyqDNgfzgmw==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"tslib": "^2.2.0"
|
||||
},
|
||||
@@ -3841,9 +3847,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@ng-web-apis/intersection-observer": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@ng-web-apis/intersection-observer/-/intersection-observer-3.2.0.tgz",
|
||||
"integrity": "sha512-EhwqEZJFKR9pz55TWp82qyWTXdg8TZeMP6bUw26bVHz8CTkgrpzaXdtxurMTvJ/+gwuFy4JSJLjBeV9nfZ/SXA==",
|
||||
"version": "3.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@ng-web-apis/intersection-observer/-/intersection-observer-3.2.3.tgz",
|
||||
"integrity": "sha512-0yp+rr6ZEyF2vz4zYlMZ1GNtTHQziKajCurqAycZkSXVUdon7MhfiY/PiTr8xklTr40DjrF4anXV7oUAaA0szQ==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"tslib": "^2.2.0"
|
||||
},
|
||||
@@ -3853,9 +3860,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@ng-web-apis/mutation-observer": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@ng-web-apis/mutation-observer/-/mutation-observer-3.2.1.tgz",
|
||||
"integrity": "sha512-a7krkMx0e9cfnutClwDylWjbTQVRHUP3oUik/nBvUdKlk/Q4anNww9aIKJ64VgiXR+1ZF8OmHGl0+XUzN6xP9Q==",
|
||||
"version": "3.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@ng-web-apis/mutation-observer/-/mutation-observer-3.2.3.tgz",
|
||||
"integrity": "sha512-iFwxut1cw94lTXnloDMBRanqNTvEjbnigWkTowlPH3QY16ysTKuC51JeonRuARW4K3bbDGbXiLUYYZWKQaDfKw==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"tslib": "^2.2.0"
|
||||
},
|
||||
@@ -3865,9 +3873,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@ng-web-apis/resize-observer": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@ng-web-apis/resize-observer/-/resize-observer-3.2.1.tgz",
|
||||
"integrity": "sha512-r1YaZUo6DIDeR+4/C/pM4Ar0eTQBxjK0FUhYYJ512EnN8RqAn8d3a0wM8ZYunucwDICwW1sx4IIV6PZ2G77xsg==",
|
||||
"version": "3.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@ng-web-apis/resize-observer/-/resize-observer-3.2.3.tgz",
|
||||
"integrity": "sha512-x3KxBZSragzdQlkbY9tiHY0lVlkOFD7Y34rzXdBJ7PTnIvlq43X/tN31Mmb3R0Np4vsarWqnhO6Y42ljudsWdA==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"tslib": "^2.2.0"
|
||||
},
|
||||
@@ -4161,60 +4170,63 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@taiga-ui/addon-charts": {
|
||||
"version": "3.86.0",
|
||||
"resolved": "https://registry.npmjs.org/@taiga-ui/addon-charts/-/addon-charts-3.86.0.tgz",
|
||||
"integrity": "sha512-Du/85qqaj8hpFSI6hPuFeIhtE93Z6WSkYZLt0gvnsaCb2qSAg8D4oHSogrtF1rsWGGoM+fvXjD7UEUw9GzFIPg==",
|
||||
"version": "3.96.0",
|
||||
"resolved": "https://registry.npmjs.org/@taiga-ui/addon-charts/-/addon-charts-3.96.0.tgz",
|
||||
"integrity": "sha512-vU8fZhwdg+sWOPJNnIrEtuuVkoFjQKeMhvk4f68oHBXUa0XUESS+qNeAfstvow6xnAZJrhxYtMoDuH/cgC7kNg==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"tslib": "^2.6.2"
|
||||
"tslib": ">=2.7.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/common": ">=12.0.0",
|
||||
"@angular/core": ">=12.0.0",
|
||||
"@ng-web-apis/common": "^3.0.6",
|
||||
"@taiga-ui/cdk": "^3.86.0",
|
||||
"@taiga-ui/core": "^3.86.0",
|
||||
"@tinkoff/ng-polymorpheus": "^4.3.0"
|
||||
"@ng-web-apis/common": ">=3.2.3 <4",
|
||||
"@taiga-ui/cdk": ">=3.96.0 <4",
|
||||
"@taiga-ui/core": ">=3.96.0 <4",
|
||||
"@tinkoff/ng-polymorpheus": ">=4.3.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@taiga-ui/addon-commerce": {
|
||||
"version": "3.86.0",
|
||||
"resolved": "https://registry.npmjs.org/@taiga-ui/addon-commerce/-/addon-commerce-3.86.0.tgz",
|
||||
"integrity": "sha512-8QSB490ckI4jnU+1sQ3x8os2GVE162hbvzPVYIZ0TruoeXl076dAz6PT2WRaFwjcaCAIGsuaQgQ4Cv02NjkiYQ==",
|
||||
"version": "3.96.0",
|
||||
"resolved": "https://registry.npmjs.org/@taiga-ui/addon-commerce/-/addon-commerce-3.96.0.tgz",
|
||||
"integrity": "sha512-Y1MACB6KrQVnNjgeKQrNfbz51jMXbU7j83sL28+6q8DS9LNv4DVcv/r/UvK2VZ1PhESkBU85NJAIHf5iy9GN4g==",
|
||||
"license": "Apache-2.0",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.6.2"
|
||||
"tslib": ">=2.7.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/common": ">=12.0.0",
|
||||
"@angular/core": ">=12.0.0",
|
||||
"@angular/forms": ">=12.0.0",
|
||||
"@maskito/angular": "^1.9.0",
|
||||
"@maskito/core": "^1.9.0",
|
||||
"@maskito/kit": "^1.9.0",
|
||||
"@ng-web-apis/common": "^3.0.6",
|
||||
"@taiga-ui/cdk": "^3.86.0",
|
||||
"@taiga-ui/core": "^3.86.0",
|
||||
"@taiga-ui/i18n": "^3.86.0",
|
||||
"@taiga-ui/kit": "^3.86.0",
|
||||
"@tinkoff/ng-polymorpheus": "^4.3.0",
|
||||
"@maskito/angular": ">=1.9.0 <2",
|
||||
"@maskito/core": ">=1.9.0 <2",
|
||||
"@maskito/kit": ">=1.9.0 <2",
|
||||
"@ng-web-apis/common": ">=3.2.3 <4",
|
||||
"@taiga-ui/cdk": ">=3.96.0 <4",
|
||||
"@taiga-ui/core": ">=3.96.0 <4",
|
||||
"@taiga-ui/i18n": ">=3.96.0 <4",
|
||||
"@taiga-ui/kit": ">=3.96.0 <4",
|
||||
"@tinkoff/ng-polymorpheus": ">=4.3.0",
|
||||
"rxjs": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@taiga-ui/cdk": {
|
||||
"version": "3.86.0",
|
||||
"resolved": "https://registry.npmjs.org/@taiga-ui/cdk/-/cdk-3.86.0.tgz",
|
||||
"integrity": "sha512-aVbnW01Oh0Er1sHKVGHP8W05mOSKxjSzFE3Qx4iF4T6KW7Rlz9HZoNx5ADMg0TATYChtWh9Kwjo8I4LSVj2ZUw==",
|
||||
"version": "3.96.0",
|
||||
"resolved": "https://registry.npmjs.org/@taiga-ui/cdk/-/cdk-3.96.0.tgz",
|
||||
"integrity": "sha512-y1T4+Olhys370ePT8SvZpMlOConDG6bLxjo6jOvFI6D6w0nEgqRxxFDBcdoHxgMWJZdAg7lRLEtN9dHEwKaABA==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@ng-web-apis/common": "3.0.6",
|
||||
"@ng-web-apis/mutation-observer": "3.1.0",
|
||||
"@ng-web-apis/resize-observer": "3.0.6",
|
||||
"@tinkoff/ng-event-plugins": "3.2.0",
|
||||
"@tinkoff/ng-polymorpheus": "4.3.0",
|
||||
"tslib": "2.6.2"
|
||||
"@ng-web-apis/common": "^3.2.3",
|
||||
"@ng-web-apis/mutation-observer": "^3.2.3",
|
||||
"@ng-web-apis/resize-observer": "^3.2.3",
|
||||
"@tinkoff/ng-event-plugins": "^3.2.0",
|
||||
"@tinkoff/ng-polymorpheus": "^4.3.0",
|
||||
"tslib": "^2.7.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"ng-morph": "4.0.5",
|
||||
"parse5": "6.0.1"
|
||||
"ng-morph": "^4.8.2",
|
||||
"parse5": "^6.0.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/animations": ">=12.0.0",
|
||||
@@ -4224,42 +4236,166 @@
|
||||
"rxjs": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@taiga-ui/cdk/node_modules/@ng-web-apis/mutation-observer": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@ng-web-apis/mutation-observer/-/mutation-observer-3.1.0.tgz",
|
||||
"integrity": "sha512-MFN0TLLBMFJJPpXkGFe9ChRCSOKvMHZRRtBq5jHWS7tv5/CtdUkqW5CU7RC9KTzZjGeMzYe0cXO4JRkjL5aZ9g==",
|
||||
"node_modules/@taiga-ui/cdk/node_modules/@angular-devkit/core": {
|
||||
"version": "18.2.9",
|
||||
"resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-18.2.9.tgz",
|
||||
"integrity": "sha512-bsVt//5E0ua7FZfO0dCF/qGGY6KQD34/bNGyRu5B6HedimpdU2/0PGDptksU5v3yKEc9gNw0xC6mT0UsY/R9pA==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"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": {
|
||||
"@angular/core": ">=12.0.0",
|
||||
"@ng-web-apis/common": ">=2.0.0"
|
||||
"chokidar": "^3.5.2"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"chokidar": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@taiga-ui/cdk/node_modules/@ng-web-apis/resize-observer": {
|
||||
"version": "3.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@ng-web-apis/resize-observer/-/resize-observer-3.0.6.tgz",
|
||||
"integrity": "sha512-QdGYdEdC0AzFonLfNOnyYyeCwnvK9jlskoeefvJN3Yyvds3ivBrrTjpeDOdiLsQpCPBp9/673imgq7355vkQow==",
|
||||
"node_modules/@taiga-ui/cdk/node_modules/@angular-devkit/schematics": {
|
||||
"version": "18.2.9",
|
||||
"resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-18.2.9.tgz",
|
||||
"integrity": "sha512-aIY5/IomDOINGCtFYi77uo0acDpdQNNCighfBBUGEBNMQ1eE3oGNGpLAH/qWeuxJndgmxrdKsvws9DdT46kLig==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"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": {
|
||||
"@angular/core": ">=12.0.0",
|
||||
"@ng-web-apis/common": ">=2.0.0"
|
||||
"ajv": "^8.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"ajv": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@taiga-ui/cdk/node_modules/tslib": {
|
||||
"version": "2.6.2",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
|
||||
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
|
||||
"node_modules/@taiga-ui/cdk/node_modules/jsonc-parser": {
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz",
|
||||
"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": {
|
||||
"version": "3.86.0",
|
||||
"resolved": "https://registry.npmjs.org/@taiga-ui/core/-/core-3.86.0.tgz",
|
||||
"integrity": "sha512-diQKOnPtDDfxPOMk6wLRq8nyDVfNSPSNy+1TeyqzUgOvJ6XAjfaBXGsL3iuR7AN8+sz/b3rJmBce+vdw6FjMLQ==",
|
||||
"version": "3.96.0",
|
||||
"resolved": "https://registry.npmjs.org/@taiga-ui/core/-/core-3.96.0.tgz",
|
||||
"integrity": "sha512-0w2Jpesb2oM+5aMTfSKFzzYdfPDHXq0fhE6TN4Eutc9LO4Lyh6Hg0KPfoHmw8Tj6wg4KxBcdeAj/opNehWwrVw==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@taiga-ui/i18n": "^3.86.0",
|
||||
"tslib": "^2.6.2"
|
||||
"@taiga-ui/i18n": "^3.96.0",
|
||||
"tslib": ">=2.7.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/animations": ">=12.0.0",
|
||||
@@ -4268,81 +4404,85 @@
|
||||
"@angular/forms": ">=12.0.0",
|
||||
"@angular/platform-browser": ">=12.0.0",
|
||||
"@angular/router": ">=12.0.0",
|
||||
"@ng-web-apis/common": "^3.0.6",
|
||||
"@ng-web-apis/mutation-observer": "^3.1.0",
|
||||
"@taiga-ui/cdk": "^3.86.0",
|
||||
"@taiga-ui/i18n": "^3.86.0",
|
||||
"@tinkoff/ng-event-plugins": "^3.2.0",
|
||||
"@tinkoff/ng-polymorpheus": "^4.3.0",
|
||||
"@ng-web-apis/common": ">=3.2.3 <4",
|
||||
"@ng-web-apis/mutation-observer": ">=3.2.3 <4",
|
||||
"@taiga-ui/cdk": ">=3.96.0 <4",
|
||||
"@taiga-ui/i18n": ">=3.96.0 <4",
|
||||
"@tinkoff/ng-event-plugins": ">=3.2.0 <4",
|
||||
"@tinkoff/ng-polymorpheus": ">=4.3.0",
|
||||
"rxjs": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@taiga-ui/experimental": {
|
||||
"version": "3.86.0",
|
||||
"resolved": "https://registry.npmjs.org/@taiga-ui/experimental/-/experimental-3.86.0.tgz",
|
||||
"integrity": "sha512-ACjoRVeX5MgsNJsiu2ukliXLD2mfEWm8Vtmk78vqcnkyPUmy1ZWK4sG3p5ybFN8AdIMHkblVq0l+x2qAwr/+LQ==",
|
||||
"version": "3.96.0",
|
||||
"resolved": "https://registry.npmjs.org/@taiga-ui/experimental/-/experimental-3.96.0.tgz",
|
||||
"integrity": "sha512-AxEaYieouK3NzkGzOVTojnHBAd/eRw5D2sVAK+SQdBFdBjQiRGk/FKzZhOWpDOQOcIN+lhpDGpth3KV30+AgFQ==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"tslib": "^2.6.2"
|
||||
"tslib": ">=2.7.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/common": ">=12.0.0",
|
||||
"@angular/core": ">=12.0.0",
|
||||
"@taiga-ui/addon-commerce": "^3.86.0",
|
||||
"@taiga-ui/cdk": "^3.86.0",
|
||||
"@taiga-ui/core": "^3.86.0",
|
||||
"@taiga-ui/kit": "^3.86.0",
|
||||
"@tinkoff/ng-polymorpheus": "^4.3.0",
|
||||
"@taiga-ui/addon-commerce": ">=3.96.0 <4",
|
||||
"@taiga-ui/cdk": ">=3.96.0 <4",
|
||||
"@taiga-ui/core": ">=3.96.0 <4",
|
||||
"@taiga-ui/kit": ">=3.96.0 <4",
|
||||
"@tinkoff/ng-polymorpheus": ">=4.3.0",
|
||||
"rxjs": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@taiga-ui/i18n": {
|
||||
"version": "3.86.0",
|
||||
"resolved": "https://registry.npmjs.org/@taiga-ui/i18n/-/i18n-3.86.0.tgz",
|
||||
"integrity": "sha512-8zkNhMo/QtxZ2Zp6EP/nxo4SOLwaIrX+P3X/Wt+1cjFNZUYWWfdvfHLLdNviKFPVl4RAOxvkhDfza/wkrwv+iQ==",
|
||||
"version": "3.96.0",
|
||||
"resolved": "https://registry.npmjs.org/@taiga-ui/i18n/-/i18n-3.96.0.tgz",
|
||||
"integrity": "sha512-SGO89mRhmdD3BldQJiSqDCftEjjaOKXLJFFEZWBtrhelxKX5hWJ2lL0O+WzVAMegbQqHoT60HoHrWZIlSy9tVQ==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"tslib": "^2.6.2"
|
||||
"tslib": ">=2.7.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/core": ">=12.0.0",
|
||||
"@ng-web-apis/common": "^3.0.6",
|
||||
"@ng-web-apis/common": ">=3.2.3 <4",
|
||||
"rxjs": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@taiga-ui/icons": {
|
||||
"version": "3.86.0",
|
||||
"resolved": "https://registry.npmjs.org/@taiga-ui/icons/-/icons-3.86.0.tgz",
|
||||
"integrity": "sha512-jVBEbvE/r9JG+knmXMTn/l/js3JjYi8nSGbrLCryJZZoS2izRnQARN2txABieUJm8H463CoF0rcdXlHKRuA4Ew==",
|
||||
"version": "3.96.0",
|
||||
"resolved": "https://registry.npmjs.org/@taiga-ui/icons/-/icons-3.96.0.tgz",
|
||||
"integrity": "sha512-bBuX8RGAqr2+9TRbTA4RAmq3v4pnE9ObDwoq/5CrUtE3Wr7idcl7hgfW3yeyhpdOdJJMGfbTauPBONLz2uFRCQ==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"tslib": "^2.6.2"
|
||||
"tslib": ">=2.7.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@taiga-ui/cdk": "^3.86.0"
|
||||
"@taiga-ui/cdk": ">=3.96.0 <4"
|
||||
}
|
||||
},
|
||||
"node_modules/@taiga-ui/kit": {
|
||||
"version": "3.86.0",
|
||||
"resolved": "https://registry.npmjs.org/@taiga-ui/kit/-/kit-3.86.0.tgz",
|
||||
"integrity": "sha512-naAy4pyhCaQ9+vWxqSMjbV+9KwnMxT5ybrw+MAJgMn2evzRq0FjqzyFZFog7oiRbRvgVdoWPQfBNKaaLhJcpsw==",
|
||||
"version": "3.96.0",
|
||||
"resolved": "https://registry.npmjs.org/@taiga-ui/kit/-/kit-3.96.0.tgz",
|
||||
"integrity": "sha512-gHn0AZU1kiNZU2T/LnnxLGkHC3/XNroBWCGmhxupAmL/JcsmOXsl3L8aK1rZhjS4QgkmgaC5ueVWNwdXINRnXw==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@maskito/angular": "1.9.0",
|
||||
"@maskito/core": "1.9.0",
|
||||
"@maskito/kit": "1.9.0",
|
||||
"@ng-web-apis/intersection-observer": "3.2.0",
|
||||
"text-mask-core": "5.1.2",
|
||||
"tslib": "^2.6.2"
|
||||
"@maskito/angular": "^1.9.0",
|
||||
"@maskito/core": "^1.9.0",
|
||||
"@maskito/kit": "^1.9.0",
|
||||
"@ng-web-apis/intersection-observer": "^3.2.3",
|
||||
"text-mask-core": "^5.1.2",
|
||||
"tslib": ">=2.7.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/common": ">=12.0.0",
|
||||
"@angular/core": ">=12.0.0",
|
||||
"@angular/forms": ">=12.0.0",
|
||||
"@angular/router": ">=12.0.0",
|
||||
"@ng-web-apis/common": "3.0.6",
|
||||
"@ng-web-apis/mutation-observer": "^3.1.0",
|
||||
"@ng-web-apis/resize-observer": "^3.0.6",
|
||||
"@taiga-ui/cdk": "^3.86.0",
|
||||
"@taiga-ui/core": "^3.86.0",
|
||||
"@taiga-ui/i18n": "^3.86.0",
|
||||
"@tinkoff/ng-polymorpheus": "^4.3.0",
|
||||
"@ng-web-apis/common": ">=3.2.3 <4",
|
||||
"@ng-web-apis/mutation-observer": ">=3.2.3 <4",
|
||||
"@ng-web-apis/resize-observer": ">=3.2.3 <4",
|
||||
"@taiga-ui/cdk": ">=3.96.0 <4",
|
||||
"@taiga-ui/core": ">=3.96.0 <4",
|
||||
"@taiga-ui/i18n": ">=3.96.0 <4",
|
||||
"@tinkoff/ng-polymorpheus": ">=4.3.0",
|
||||
"rxjs": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
@@ -4400,13 +4540,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@ts-morph/common": {
|
||||
"version": "0.22.0",
|
||||
"resolved": "https://registry.npmjs.org/@ts-morph/common/-/common-0.22.0.tgz",
|
||||
"integrity": "sha512-HqNBuV/oIlMKdkLshXd1zKBqNQCsuPEsgQOkfFQ/eUKjRlwndXW1AjN9LVkBEIukm00gGXSRmfkl0Wv5VXLnlw==",
|
||||
"version": "0.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@ts-morph/common/-/common-0.24.0.tgz",
|
||||
"integrity": "sha512-c1xMmNHWpNselmpIqursHeOHHBTIsJLbB+NuovbTTRCNiTLEr/U9dbJ8qy0jd/O2x5pc3seWuOUN5R2IoOTp8A==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"fast-glob": "^3.3.2",
|
||||
"minimatch": "^9.0.3",
|
||||
"minimatch": "^9.0.4",
|
||||
"mkdirp": "^3.0.1",
|
||||
"path-browserify": "^1.0.1"
|
||||
}
|
||||
@@ -4415,6 +4556,7 @@
|
||||
"version": "9.0.5",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
|
||||
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
|
||||
"license": "ISC",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"brace-expansion": "^2.0.1"
|
||||
@@ -4430,6 +4572,7 @@
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz",
|
||||
"integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"bin": {
|
||||
"mkdirp": "dist/cjs/src/bin.js"
|
||||
@@ -4613,6 +4756,7 @@
|
||||
"version": "3.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz",
|
||||
"integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==",
|
||||
"license": "MIT",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/@types/mustache": {
|
||||
@@ -5237,6 +5381,7 @@
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz",
|
||||
"integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
@@ -5252,6 +5397,7 @@
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
|
||||
"integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
@@ -5261,6 +5407,7 @@
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz",
|
||||
"integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
@@ -6088,9 +6235,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/code-block-writer": {
|
||||
"version": "12.0.0",
|
||||
"resolved": "https://registry.npmjs.org/code-block-writer/-/code-block-writer-12.0.0.tgz",
|
||||
"integrity": "sha512-q4dMFMlXtKR3XNBHyMHt/3pwYNA69EDk00lloMOaaUMKPUXBw6lpXtbu3MMVG6/uOihGnRDOlkyqsONEUj60+w==",
|
||||
"version": "13.0.3",
|
||||
"resolved": "https://registry.npmjs.org/code-block-writer/-/code-block-writer-13.0.3.tgz",
|
||||
"integrity": "sha512-Oofo0pq3IKnsFtuHqSF7TqBfr71aeyZDVJ0HpmqB7FBM2qEigL0iPONSCZSO9pE9dZTAxANe5XHG9Uy0YMv8cg==",
|
||||
"license": "MIT",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/color-convert": {
|
||||
@@ -7868,6 +8016,14 @@
|
||||
"integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==",
|
||||
"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": {
|
||||
"version": "1.17.1",
|
||||
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz",
|
||||
@@ -10651,6 +10807,7 @@
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/multimatch/-/multimatch-5.0.0.tgz",
|
||||
"integrity": "sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@types/minimatch": "^3.0.3",
|
||||
@@ -10670,6 +10827,7 @@
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0",
|
||||
@@ -10680,6 +10838,7 @@
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||
"license": "ISC",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
@@ -10781,50 +10940,6 @@
|
||||
"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": {
|
||||
"version": "14.2.2",
|
||||
"resolved": "https://registry.npmjs.org/ng-packagr/-/ng-packagr-14.2.2.tgz",
|
||||
@@ -14794,7 +14909,8 @@
|
||||
"node_modules/text-mask-core": {
|
||||
"version": "5.1.2",
|
||||
"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": {
|
||||
"version": "0.2.0",
|
||||
@@ -14880,13 +14996,14 @@
|
||||
"integrity": "sha512-UFYaKgfqlg9FROK7bdpYqFwG1CJvP4kOJdjXuWoqxo9jCmANoDw1GxkSCpJgoTeIiSTaTH5Qr1klSspb8c+ydg=="
|
||||
},
|
||||
"node_modules/ts-morph": {
|
||||
"version": "21.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ts-morph/-/ts-morph-21.0.1.tgz",
|
||||
"integrity": "sha512-dbDtVdEAncKctzrVZ+Nr7kHpHkv+0JDJb2MjjpBaj8bFeCkePU9rHfMklmhuLFnpeq/EJZk2IhStY6NzqgjOkg==",
|
||||
"version": "23.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ts-morph/-/ts-morph-23.0.0.tgz",
|
||||
"integrity": "sha512-FcvFx7a9E8TUe6T3ShihXJLiJOiqyafzFKUO4aqIHDUCIvADdGNShcbc2W5PMr3LerXRv7mafvFZ9lRENxJmug==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@ts-morph/common": "~0.22.0",
|
||||
"code-block-writer": "^12.0.0"
|
||||
"@ts-morph/common": "~0.24.0",
|
||||
"code-block-writer": "^13.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/ts-node": {
|
||||
@@ -14933,9 +15050,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/tslib": {
|
||||
"version": "2.6.3",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz",
|
||||
"integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ=="
|
||||
"version": "2.8.0",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.0.tgz",
|
||||
"integrity": "sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==",
|
||||
"license": "0BSD"
|
||||
},
|
||||
"node_modules/tslint": {
|
||||
"version": "6.1.3",
|
||||
|
||||
@@ -43,20 +43,20 @@
|
||||
"@angular/service-worker": "^14.2.2",
|
||||
"@ionic/angular": "^6.1.15",
|
||||
"@materia-ui/ngx-monaco-editor": "^6.0.0",
|
||||
"@ng-web-apis/common": "^3.0.6",
|
||||
"@ng-web-apis/mutation-observer": "^3.2.1",
|
||||
"@ng-web-apis/resize-observer": "^3.2.1",
|
||||
"@ng-web-apis/common": "^3.2.3",
|
||||
"@ng-web-apis/mutation-observer": "^3.2.3",
|
||||
"@ng-web-apis/resize-observer": "^3.2.3",
|
||||
"@noble/curves": "^1.4.0",
|
||||
"@noble/hashes": "^1.4.0",
|
||||
"@start9labs/argon2": "^0.2.2",
|
||||
"@start9labs/emver": "^0.1.5",
|
||||
"@start9labs/start-sdk": "file:../sdk/baseDist",
|
||||
"@taiga-ui/addon-charts": "3.86.0",
|
||||
"@taiga-ui/cdk": "3.86.0",
|
||||
"@taiga-ui/core": "3.86.0",
|
||||
"@taiga-ui/experimental": "3.86.0",
|
||||
"@taiga-ui/icons": "3.86.0",
|
||||
"@taiga-ui/kit": "3.86.0",
|
||||
"@taiga-ui/addon-charts": "3.96.0",
|
||||
"@taiga-ui/cdk": "3.96.0",
|
||||
"@taiga-ui/core": "3.96.0",
|
||||
"@taiga-ui/experimental": "3.96.0",
|
||||
"@taiga-ui/icons": "3.96.0",
|
||||
"@taiga-ui/kit": "3.96.0",
|
||||
"@tinkoff/ng-dompurify": "4.0.0",
|
||||
"@tinkoff/ng-event-plugins": "3.2.0",
|
||||
"angular-svg-round-progressbar": "^9.0.0",
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
import { CommonModule } from '@angular/common'
|
||||
import { ChangeDetectionStrategy, Component, Input } from '@angular/core'
|
||||
import { T } from '@start9labs/start-sdk'
|
||||
import { TuiFadeModule, TuiTitleModule } from '@taiga-ui/experimental'
|
||||
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({
|
||||
standalone: true,
|
||||
selector: 'app-action-success-group',
|
||||
template: `
|
||||
<p *ngFor="let item of value?.value">
|
||||
<app-action-success-item
|
||||
*ngIf="isSingle(item)"
|
||||
[value]="item"
|
||||
></app-action-success-item>
|
||||
<tui-accordion-item *ngIf="!isSingle(item)" size="s">
|
||||
<div tuiFade>{{ item.name }}</div>
|
||||
<p *ngFor="let member of group.value">
|
||||
<app-action-success-member
|
||||
*ngIf="member.type === 'single'"
|
||||
[member]="member"
|
||||
></app-action-success-member>
|
||||
<tui-accordion-item *ngIf="member.type === 'group'">
|
||||
<div tuiFade>{{ member.name }}</div>
|
||||
<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>
|
||||
</tui-accordion-item>
|
||||
</p>
|
||||
@@ -37,18 +37,12 @@ import { ActionSuccessItemComponent } from './action-success-item.component'
|
||||
imports: [
|
||||
CommonModule,
|
||||
TuiTitleModule,
|
||||
ActionSuccessItemComponent,
|
||||
ActionSuccessMemberComponent,
|
||||
TuiAccordionModule,
|
||||
TuiFadeModule,
|
||||
],
|
||||
})
|
||||
export class ActionSuccessGroupComponent {
|
||||
@Input()
|
||||
value?: T.ActionResultV1 & { type: 'object' }
|
||||
|
||||
isSingle(
|
||||
value: T.ActionResultV1,
|
||||
): value is T.ActionResultV1 & { type: 'string' } {
|
||||
return value.type === 'string'
|
||||
}
|
||||
group!: GroupResult
|
||||
}
|
||||
|
||||
@@ -9,41 +9,38 @@ import {
|
||||
ViewChild,
|
||||
} from '@angular/core'
|
||||
import { FormsModule } from '@angular/forms'
|
||||
import { T } from '@start9labs/start-sdk'
|
||||
import {
|
||||
TuiDialogService,
|
||||
TuiLabelModule,
|
||||
TuiTextfieldComponent,
|
||||
TuiTextfieldControllerModule,
|
||||
} from '@taiga-ui/core'
|
||||
import { TuiButtonModule } from '@taiga-ui/experimental'
|
||||
import { TuiButtonModule, TuiTitleModule } from '@taiga-ui/experimental'
|
||||
import { TuiInputModule } from '@taiga-ui/kit'
|
||||
import { QrCodeModule } from 'ng-qrcode'
|
||||
import { ActionSuccessGroupComponent } from './action-success-group.component'
|
||||
import { T } from '@start9labs/start-sdk'
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
selector: 'app-action-success-item',
|
||||
selector: 'app-action-success-member',
|
||||
template: `
|
||||
<p *ngIf="!parent" class="qr">
|
||||
<ng-container *ngTemplateOutlet="qr"></ng-container>
|
||||
</p>
|
||||
<label [tuiLabel]="value.description">
|
||||
<tui-input
|
||||
[readOnly]="true"
|
||||
[ngModel]="value.value"
|
||||
[tuiTextfieldCustomContent]="actions"
|
||||
>
|
||||
<input
|
||||
tuiTextfield
|
||||
[style.border-inline-end-width.rem]="border"
|
||||
[type]="value.masked && masked ? 'password' : 'text'"
|
||||
/>
|
||||
</tui-input>
|
||||
<tui-input
|
||||
[readOnly]="true"
|
||||
[ngModel]="member.value"
|
||||
[tuiTextfieldCustomContent]="actions"
|
||||
>
|
||||
{{ member.name }}
|
||||
<input
|
||||
tuiTextfield
|
||||
[style.border-inline-end-width.rem]="border"
|
||||
[type]="member.masked && masked ? 'password' : 'text'"
|
||||
/>
|
||||
</tui-input>
|
||||
<label *ngIf="member.description" [style.padding-top.rem]="0.25" tuiTitle>
|
||||
<span tuiSubtitle [style.opacity]="0.8">{{ member.description }}</span>
|
||||
</label>
|
||||
<ng-template #actions>
|
||||
<button
|
||||
*ngIf="value.masked"
|
||||
*ngIf="member.masked"
|
||||
tuiIconButton
|
||||
appearance="icon"
|
||||
size="s"
|
||||
@@ -56,7 +53,7 @@ import { ActionSuccessGroupComponent } from './action-success-group.component'
|
||||
Reveal/Hide
|
||||
</button>
|
||||
<button
|
||||
*ngIf="value.copyable"
|
||||
*ngIf="member.copyable"
|
||||
tuiIconButton
|
||||
appearance="icon"
|
||||
size="s"
|
||||
@@ -69,7 +66,7 @@ import { ActionSuccessGroupComponent } from './action-success-group.component'
|
||||
Copy
|
||||
</button>
|
||||
<button
|
||||
*ngIf="value.qr && parent"
|
||||
*ngIf="member.qr"
|
||||
tuiIconButton
|
||||
appearance="icon"
|
||||
size="s"
|
||||
@@ -84,12 +81,12 @@ import { ActionSuccessGroupComponent } from './action-success-group.component'
|
||||
</ng-template>
|
||||
<ng-template #qr>
|
||||
<qr-code
|
||||
[value]="value.value"
|
||||
[style.filter]="value.masked && masked ? 'blur(0.5rem)' : null"
|
||||
[value]="member.value"
|
||||
[style.filter]="member.masked && masked ? 'blur(0.5rem)' : null"
|
||||
size="350"
|
||||
></qr-code>
|
||||
<button
|
||||
*ngIf="value.masked && masked"
|
||||
*ngIf="member.masked && masked"
|
||||
tuiIconButton
|
||||
class="reveal"
|
||||
iconLeft="tuiIconEye"
|
||||
@@ -122,37 +119,25 @@ import { ActionSuccessGroupComponent } from './action-success-group.component'
|
||||
TuiTextfieldControllerModule,
|
||||
TuiButtonModule,
|
||||
QrCodeModule,
|
||||
TuiLabelModule,
|
||||
TuiTitleModule,
|
||||
],
|
||||
})
|
||||
export class ActionSuccessItemComponent {
|
||||
export class ActionSuccessMemberComponent {
|
||||
@ViewChild(TuiTextfieldComponent, { read: ElementRef })
|
||||
private readonly input!: ElementRef<HTMLInputElement>
|
||||
private readonly dialogs = inject(TuiDialogService)
|
||||
|
||||
readonly parent = inject(ActionSuccessGroupComponent, {
|
||||
optional: true,
|
||||
})
|
||||
|
||||
@Input()
|
||||
value!: T.ActionResultV1 & { type: 'string' }
|
||||
member!: T.ActionResultMember & { type: 'single' }
|
||||
|
||||
masked = true
|
||||
|
||||
get border(): number {
|
||||
let border = 0
|
||||
|
||||
if (this.value.masked) {
|
||||
border += 2
|
||||
}
|
||||
|
||||
if (this.value.copyable) {
|
||||
border += 2
|
||||
}
|
||||
|
||||
if (this.value.qr && this.parent) {
|
||||
border += 2
|
||||
}
|
||||
if (this.member.masked) border += 2
|
||||
if (this.member.copyable) border += 2
|
||||
if (this.member.qr) border += 2
|
||||
|
||||
return border
|
||||
}
|
||||
@@ -160,7 +145,7 @@ export class ActionSuccessItemComponent {
|
||||
show(template: TemplateRef<any>) {
|
||||
const masked = this.masked
|
||||
|
||||
this.masked = this.value.masked
|
||||
this.masked = this.member.masked
|
||||
this.dialogs
|
||||
.open(template, { label: 'Scan this QR', size: 's' })
|
||||
.subscribe({
|
||||
@@ -179,6 +164,6 @@ export class ActionSuccessItemComponent {
|
||||
el.focus()
|
||||
el.select()
|
||||
el.ownerDocument.execCommand('copy')
|
||||
el.type = this.masked && this.value.masked ? 'password' : 'text'
|
||||
el.type = this.masked && this.member.masked ? 'password' : 'text'
|
||||
}
|
||||
}
|
||||
@@ -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'
|
||||
}
|
||||
}
|
||||
@@ -1,36 +1,36 @@
|
||||
import { CommonModule } from '@angular/common'
|
||||
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 { RR } from 'src/app/services/api/api.types'
|
||||
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({
|
||||
standalone: true,
|
||||
template: `
|
||||
<ng-container tuiTextfieldSize="m" [tuiTextfieldLabelOutside]="true">
|
||||
<app-action-success-item
|
||||
*ngIf="item"
|
||||
[value]="item"
|
||||
></app-action-success-item>
|
||||
<app-action-success-group
|
||||
*ngIf="group"
|
||||
[value]="group"
|
||||
></app-action-success-group>
|
||||
</ng-container>
|
||||
<p *ngIf="data.message">{{ data.message }}</p>
|
||||
<app-action-success-single
|
||||
*ngIf="single"
|
||||
[single]="single"
|
||||
></app-action-success-single>
|
||||
<app-action-success-group
|
||||
*ngIf="group"
|
||||
[group]="group"
|
||||
></app-action-success-group>
|
||||
`,
|
||||
imports: [
|
||||
CommonModule,
|
||||
ActionSuccessGroupComponent,
|
||||
ActionSuccessItemComponent,
|
||||
TuiTextfieldControllerModule,
|
||||
ActionSuccessSingleComponent,
|
||||
],
|
||||
})
|
||||
export class ActionSuccessPage {
|
||||
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 group = this.data?.type === 'object' ? this.data : null
|
||||
readonly single = this.data.result.type === 'single' ? this.data.result : null
|
||||
readonly group = this.data.result.type === 'group' ? this.data.result : null
|
||||
}
|
||||
|
||||
7
web/projects/ui/src/app/modals/action-success/types.ts
Normal file
7
web/projects/ui/src/app/modals/action-success/types.ts
Normal 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' }
|
||||
@@ -118,13 +118,17 @@ export class ActionService {
|
||||
input: input || null,
|
||||
})
|
||||
|
||||
if (res) {
|
||||
if (!res) return true
|
||||
|
||||
if (res.result) {
|
||||
this.dialogs
|
||||
.open(new PolymorpheusComponent(ActionSuccessPage), {
|
||||
label: res.name,
|
||||
label: res.title,
|
||||
data: res,
|
||||
})
|
||||
.subscribe()
|
||||
} else if (res.message) {
|
||||
this.dialogs.open(res.message, { label: res.title }).subscribe()
|
||||
}
|
||||
return true // needed to dismiss original modal/alert
|
||||
} catch (e: any) {
|
||||
|
||||
@@ -1049,77 +1049,91 @@ export module Mock {
|
||||
},
|
||||
}
|
||||
|
||||
export const ActionRes: RR.ActionRes = {
|
||||
export const ActionResMessage: RR.ActionRes = {
|
||||
version: '1',
|
||||
type: 'string',
|
||||
name: 'New Password',
|
||||
description:
|
||||
'Action was run successfully Action was run successfully Action was run successfully Action was run successfully Action was run successfully',
|
||||
copyable: true,
|
||||
qr: true,
|
||||
masked: true,
|
||||
value: 'iwejdoiewdhbew',
|
||||
title: 'New Password',
|
||||
message:
|
||||
'Action was run successfully and smoothly and fully and all is good on the western front.',
|
||||
result: null,
|
||||
}
|
||||
|
||||
export const ActionProperties: RR.ActionRes = {
|
||||
export const ActionResSingle: RR.ActionRes = {
|
||||
version: '1',
|
||||
type: 'object',
|
||||
name: 'Properties',
|
||||
value: [
|
||||
{
|
||||
type: 'string',
|
||||
name: 'LND Connect',
|
||||
description: 'This is some information about the thing.',
|
||||
copyable: true,
|
||||
qr: true,
|
||||
masked: true,
|
||||
value:
|
||||
'lndconnect://udlyfq2mxa4355pt7cqlrdipnvk2tsl4jtsdw7zaeekenufwcev2wlad.onion:10009?cert=MIICJTCCAcugAwIBAgIRAOyq85fqAiA3U3xOnwhH678wCgYIKoZIzj0EAwIwODEfMB0GAkUEChMWbG5kIGF1dG9nZW5lcmF0ZWQgY2VydDEVMBMGA1UEAxMMNTc0OTkwMzIyYzZlMB4XDTIwMTAyNjA3MzEyN1oXDTIxMTIyMTA3MzEyN1owODEfMB0GA1UEChMWbG5kIGF1dG9nZW5lcmF0ZWQgY2VydDEVMBMGA1UEAxMMNTc0OTkwMzIyYzZlMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEKqfhAMMZdY-eFnU5P4bGrQTSx0lo7m8u4V0yYkzUM6jlql_u31_mU2ovLTj56wnZApkEjoPl6fL2yasZA2wiy6OBtTCBsjAOBgNVHQ8BAf8EBAMCAqQwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDwYDVR0TAQH_BAUwAwEB_zAdBgNVHQ4EFgQUYQ9uIO6spltnVCx4rLFL5BvBF9IwWwYDVR0RBFQwUoIMNTc0OTkwMzIyYzZlgglsb2NhbGhvc3SCBHVuaXiCCnVuaXhwYWNrZXSCB2J1ZmNvbm6HBH8AAAGHEAAAAAAAAAAAAAAAAAAAAAGHBKwSAAswCgYIKoZIzj0EAwIDSAAwRQIgVZH2Z2KlyAVY2Q2aIQl0nsvN-OEN49wreFwiBqlxNj4CIQD5_JbpuBFJuf81I5J0FQPtXY-4RppWOPZBb-y6-rkIUQ&macaroon=AgEDbG5kAusBAwoQuA8OUMeQ8Fr2h-f65OdXdRIBMBoWCgdhZGRyZXNzEgRyZWFkEgV3cml0ZRoTCgRpbmZvEgRyZWFkEgV3cml0ZRoXCghpbnZvaWNlcxIEcmVhZBIFd3JpdGUaFAoIbWFjYXJvb24SCGdlbmVyYXRlGhYKB21lc3NhZ2USBHJlYWQSBXdyaXRlGhcKCG9mZmNoYWluEgRyZWFkEgV3cml0ZRoWCgdvbmNoYWluEgRyZWFkEgV3cml0ZRoUCgVwZWVycxIEcmVhZBIFd3JpdGUaGAoGc2lnbmVyEghnZW5lcmF0ZRIEcmVhZAAABiCYsRUoUWuAHAiCSLbBR7b_qULDSl64R8LIU2aqNIyQfA',
|
||||
},
|
||||
{
|
||||
type: 'object',
|
||||
name: 'Nested Stuff',
|
||||
description: 'This is a nested thing metric',
|
||||
value: [
|
||||
{
|
||||
type: 'string',
|
||||
name: 'Last Name',
|
||||
description: 'The last name of the user',
|
||||
copyable: true,
|
||||
qr: true,
|
||||
masked: false,
|
||||
value: 'Hill',
|
||||
},
|
||||
{
|
||||
type: 'string',
|
||||
name: 'Age',
|
||||
description: 'The age of the user',
|
||||
copyable: false,
|
||||
qr: false,
|
||||
masked: false,
|
||||
value: '35',
|
||||
},
|
||||
{
|
||||
type: 'string',
|
||||
name: 'Password',
|
||||
description: 'A secret password',
|
||||
copyable: true,
|
||||
qr: false,
|
||||
masked: true,
|
||||
value: 'password123',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'string',
|
||||
name: 'Another Value',
|
||||
description: 'Some more information about the service.',
|
||||
copyable: false,
|
||||
qr: true,
|
||||
masked: false,
|
||||
value: 'https://guessagain.com',
|
||||
},
|
||||
],
|
||||
title: 'New Password',
|
||||
message:
|
||||
'Action was run successfully and smoothly and fully and all is good on the western front.',
|
||||
result: {
|
||||
type: 'single',
|
||||
copyable: true,
|
||||
qr: true,
|
||||
masked: true,
|
||||
value: 'iwejdoiewdhbew',
|
||||
},
|
||||
}
|
||||
|
||||
export const ActionResGroup: RR.ActionRes = {
|
||||
version: '1',
|
||||
title: 'Properties',
|
||||
message:
|
||||
'Successfully retrieved properties. Here is a bunch of useful information about this service.',
|
||||
result: {
|
||||
type: 'group',
|
||||
value: [
|
||||
{
|
||||
type: 'single',
|
||||
name: 'LND Connect',
|
||||
description: 'This is some information about the thing.',
|
||||
copyable: true,
|
||||
qr: true,
|
||||
masked: true,
|
||||
value:
|
||||
'lndconnect://udlyfq2mxa4355pt7cqlrdipnvk2tsl4jtsdw7zaeekenufwcev2wlad.onion:10009?cert=MIICJTCCAcugAwIBAgIRAOyq85fqAiA3U3xOnwhH678wCgYIKoZIzj0EAwIwODEfMB0GAkUEChMWbG5kIGF1dG9nZW5lcmF0ZWQgY2VydDEVMBMGA1UEAxMMNTc0OTkwMzIyYzZlMB4XDTIwMTAyNjA3MzEyN1oXDTIxMTIyMTA3MzEyN1owODEfMB0GA1UEChMWbG5kIGF1dG9nZW5lcmF0ZWQgY2VydDEVMBMGA1UEAxMMNTc0OTkwMzIyYzZlMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEKqfhAMMZdY-eFnU5P4bGrQTSx0lo7m8u4V0yYkzUM6jlql_u31_mU2ovLTj56wnZApkEjoPl6fL2yasZA2wiy6OBtTCBsjAOBgNVHQ8BAf8EBAMCAqQwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDwYDVR0TAQH_BAUwAwEB_zAdBgNVHQ4EFgQUYQ9uIO6spltnVCx4rLFL5BvBF9IwWwYDVR0RBFQwUoIMNTc0OTkwMzIyYzZlgglsb2NhbGhvc3SCBHVuaXiCCnVuaXhwYWNrZXSCB2J1ZmNvbm6HBH8AAAGHEAAAAAAAAAAAAAAAAAAAAAGHBKwSAAswCgYIKoZIzj0EAwIDSAAwRQIgVZH2Z2KlyAVY2Q2aIQl0nsvN-OEN49wreFwiBqlxNj4CIQD5_JbpuBFJuf81I5J0FQPtXY-4RppWOPZBb-y6-rkIUQ&macaroon=AgEDbG5kAusBAwoQuA8OUMeQ8Fr2h-f65OdXdRIBMBoWCgdhZGRyZXNzEgRyZWFkEgV3cml0ZRoTCgRpbmZvEgRyZWFkEgV3cml0ZRoXCghpbnZvaWNlcxIEcmVhZBIFd3JpdGUaFAoIbWFjYXJvb24SCGdlbmVyYXRlGhYKB21lc3NhZ2USBHJlYWQSBXdyaXRlGhcKCG9mZmNoYWluEgRyZWFkEgV3cml0ZRoWCgdvbmNoYWluEgRyZWFkEgV3cml0ZRoUCgVwZWVycxIEcmVhZBIFd3JpdGUaGAoGc2lnbmVyEghnZW5lcmF0ZRIEcmVhZAAABiCYsRUoUWuAHAiCSLbBR7b_qULDSl64R8LIU2aqNIyQfA',
|
||||
},
|
||||
{
|
||||
type: 'group',
|
||||
name: 'Nested Stuff',
|
||||
description: 'This is a nested thing metric',
|
||||
value: [
|
||||
{
|
||||
type: 'single',
|
||||
name: 'Last Name',
|
||||
description: 'The last name of the user',
|
||||
copyable: true,
|
||||
qr: true,
|
||||
masked: false,
|
||||
value: 'Hill',
|
||||
},
|
||||
{
|
||||
type: 'single',
|
||||
name: 'Age',
|
||||
description: 'The age of the user',
|
||||
copyable: false,
|
||||
qr: false,
|
||||
masked: false,
|
||||
value: '35',
|
||||
},
|
||||
{
|
||||
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> =>
|
||||
|
||||
@@ -784,7 +784,9 @@ export class MockApiService extends ApiService {
|
||||
await pauseFor(2000)
|
||||
|
||||
if (params.actionId === 'properties') {
|
||||
return Mock.ActionProperties
|
||||
// return Mock.ActionResGroup
|
||||
return Mock.ActionResMessage
|
||||
// return Mock.ActionResSingle
|
||||
} else if (params.actionId === 'config') {
|
||||
const patch: RemoveOperation[] = [
|
||||
{
|
||||
@@ -795,7 +797,8 @@ export class MockApiService extends ApiService {
|
||||
this.mockRevision(patch)
|
||||
return null
|
||||
} else {
|
||||
return Mock.ActionRes
|
||||
return Mock.ActionResMessage
|
||||
// return Mock.ActionResSingle
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user