diff --git a/Cargo.lock b/Cargo.lock index 0351c77..5fc46dc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1929,7 +1929,10 @@ dependencies = [ "oxc_allocator", "oxc_ast", "oxc_ast_visit", + "oxc_span", + "oxc_syntax", "serde_json", + "wa-enums", "wa-ir", "wa-oxc", "wa-scan", @@ -1971,6 +1974,7 @@ dependencies = [ "oxc_parser", "oxc_span", "oxc_syntax", + "serde_json", "wa-enums", "wa-ir", "wa-oxc", diff --git a/README.md b/README.md index fef1029..3f0889a 100644 --- a/README.md +++ b/README.md @@ -14,12 +14,32 @@ WhatsApp Web ships its whole protocol (IQ stanzas, protobuf schemas, GraphQL ope | **appstate** | `appstate/index.json` (+ Rust) | app-state (syncd) action schemas + indexing | | **abprops** | `abprops/index.json` (+ Rust) | the A/B-props feature-flag registry (~1.7k flags: code, type, default) | | **enums** | `enums/index.json` (+ Rust) | the wire-enum catalog (nack codes, chat/receipt types, …) | -| **notif** | `notif/index.json` (+ Rust) | the incoming stanza-dispatch catalog: `` kinds + handlers + typed content shapes | +| **notif** | `notif/index.json` (+ Rust) | the incoming stanza-dispatch catalog: `` kinds + handlers + typed content shapes + the payload **action unions** (`w:gp2`'s 40+ group actions) | | **tokens** | `tokens/index.json` (+ `tokens.json`) | the binary-protocol token dictionaries (single-byte + 4 double-byte), wire-indexable | | **wasm** | `wasm/index.json` | the WebAssembly surface: emscripten payload names (`liboqs_wasm_wrapper.wasm`, …) + the bootloader (`bx`) handles the JS resolves their bytes through, with consuming modules | Every domain ships a JSON Schema under `generated/schema/`, and a top-level `generated/manifest.json` stamps the WhatsApp version, per-domain counts, content hashes, and extraction diagnostics. +### Validation constraints, not just field shapes + +Field shapes tell you how to *read* a stanza. They are not enough to *produce* one, nor to explain why a real client rejected the one you produced. So the IR also carries the rules WA Web's own parsers enforce — symmetric by construction, so they serve a parser and an emitter equally: + +- **Echo rules** (`assertions[].kind == "reference"`, and `referencePath` on a field) — an answer's `from` must equal the **request's** `to`, its `id` the request's `id`. `referencePath` is the argument list of WA's `attrStringFromReference`, so `["to"]` means "the request's `to`" and `["account","action"]` means "the `action` attribute of the request's `` child" — no name-matching required. An emitter that hardcodes `from="s.whatsapp.net"` makes every answer to a `g.us` request unparseable. +- **Pinned values** (`literalValue` on a field) — `type="admin"` on a successful promote, `matched="true"`/`"false"` on a blocklist update, `code=429` on a rate-limit error. `required` separates the two forms: a required pin is a hard discriminator (must be present and exact); an optional one is pinned only when present (may be omitted, must never be contradicted). +- **The per-RPC error vocabulary** (`errorArms`, plus `errorEnvelope` for a two-level error) — a **closed** set, and it differs per RPC: `BatchGetGroupInfo` accepts `400 bad-request` and `429 rate-overlimit` and **rejects `404 item-not-found`**, even though that mixin exists and other RPCs use it. Each arm pairs the `code` with the `text` that must accompany it, so an emitter cannot combine one arm's code with another's text and produce a stanza no branch accepts; an arm that range-checks instead of pinning carries `codeMin`/`codeMax`. The variant's `kind` says which side is at fault (`client_error` / `server_error`), derived from the codes rather than from the parser's name. +- **Response enums** (`enumRef` on a field) — the legal values behind an `attrStringEnum`, resolved the same way the request side already resolves them, instead of a bare `"type": "enum"`. +- **The accessor's decoded type**, kept faithful: every `attr*` / `content*` spelling WA's parsers use is classified (a `maybeAttrX` derives from `attrX`, so a flavour cannot be covered for one spelling and missed for the other), and the JID flavours stay distinct — a PN user JID and a LID user JID are different identities for the same person and must never collapse into one `string`. +- **Notification action unions** (`notifications[].actions`) — the payload inside the envelope. The `wireTag → actionType` mapping is **many-to-one** (`not_ephemeral` normalises into `ephemeral` with `duration: 0`, so branching on `not_ephemeral` is dead code) and field names are rebound (the disappearing-message timer arrives in `expiration`, but the action field is `duration`). Neither is derivable from the wire. + +Note the contract version: this raised `schemaVersion` to **2.0.0**, and it is a real major bump rather than a cautious one. Four changes need action from a 1.x consumer: + +- `AssertionKind` gained a `reference` variant, widening the value space of an existing field — a closed-enum consumer rejects the document rather than ignoring it (validating the current `iq/index.json` against the 1.0 schema fails 579 times). +- `ResponseVariantKind` gained `client_error` and `server_error`; a variant that was `error` may now be either. Match on all three, or use the `is_error()` grouping. +- A response variant's `errorCodes` / `errorTexts` / `errorCodeMin` / `errorCodeMax` / `errorClass` are **gone**, replaced by `errorArms` (+ `errorEnvelope`). The flat lists were removed rather than kept alongside because they were unsound: two independent lists cannot say which code goes with which text, and 117 variants admitted combinations the parser rejects. +- `ContentType` gained `integer`, the same closed-enum widening as the first item: a `` whose body is a number used to be reported as `string`. Live in the response children that read a big-endian integer content (`contentUint`). + +Anything the extractor sees but cannot resolve structurally is counted under `manifest.diagnostics.iq.dropsByReason` rather than omitted, so "no constraint here" and "a constraint we failed to extract" never look alike. `manifest.diagnostics.iq.constraints` and `diagnostics.notif.actions` are floor-guarded: a WA refactor that hides one of these constructs fails the update instead of silently emptying a field. + ## Quick start ```sh @@ -35,7 +55,8 @@ cargo run --release -p whatspec -- update --cache .wa-cache # Seed that same cache from the lock-pinned GitHub Release (no live bundle fetch): cargo run --release -p whatspec -- restore --from-lock generated/bundles.lock.json --cache .wa-cache -# Also resolve, download and store the client's wasm payloads (~41 MB), as .wasm: +# Also resolve, download and store the client's wasm payloads (~41 MB), as .wasm +# (a cache filename is a location label, not a content address — see the note below): cargo run --release -p whatspec -- update --cache .wa-cache --wasm-out ./wasm # Restore a locked wasm set (its own lock + its own content-addressed release asset): @@ -56,6 +77,7 @@ WhatsApp only serves the *current* bundle version — old bundle URLs 404 — so - **`generated/bundles.lock.json`** records the content SHA-256 (+ size, and origin URL when known) of every bundle that produced the committed `generated/`, plus a one-line, order-invariant `setHash` fingerprint of the whole set. - The **bytes** live in a durable, WhatsApp-independent store: a rolling **`bundle-store`** GitHub Release whose assets are **content-addressed** — `bundles--.tar.xz` (pure-Rust xz, roughly half the size of gzip; legacy `.tar.gz` assets are still read) — so a set is never overwritten with different bytes and every past commit's lock keeps resolving the exact archive it pins. Published automatically by the update workflow. + Note the two different hashes: a **release asset** is named after its *contents* (`setHash`), while a **cache** filename is named after its *URL* (the JS last segment, or `sha256(url)` for wasm) — there, the content hash lives in the cache's `manifest.json` and is what integrity is verified against. A cache filename never proves what is inside the file. - **`whatspec restore --from-lock generated/bundles.lock.json --out `** pulls that archive, verifies every bundle's SHA-256 against the lock, and writes a directory ready for `update --bundles`. Use **`--cache `** instead to seed the exact version directly into the reusable `update --cache` layout; cache metadata and integrity files are written by the same `BundleCache` implementation as a live fetch. **`scripts/regen.sh`** wraps restore + `update --check` into a one-shot, offline determinism check — also run in CI, so every commit's committed IR (each `index.json` + `WAProto.proto`) is proven reproducible from its pinned inputs. > Bootstrap: the lock and the first archive are created by the first run of the update workflow (or a manual `update --save-bundles ` followed by `scripts/publish-bundles.sh `). Until then the CI reproducibility gate stays dormant. diff --git a/crates/wa-codegen/src/emit.rs b/crates/wa-codegen/src/emit.rs index f6444e4..5055cba 100644 --- a/crates/wa-codegen/src/emit.rs +++ b/crates/wa-codegen/src/emit.rs @@ -38,26 +38,23 @@ pub(crate) fn emit_field_parse(f: &ParsedField, node_var: &str, indent: &str) -> let fmsg = rust_lit_inner(wire); let method = f.method.as_str(); - if method == wap::CONTENT_BYTES { + // Every remaining content spelling reads the node body and is typed by the canonical + // classifier, so a newly-recognized one (`contentUint`, `contentEnum`, + // `contentBytesRange`, `contentLiteralBytes`) is parsed rather than silently skipped. + if wap::is_content_method(method) { return vec![format!( - "{indent}let {name} = {node_var}.content_bytes().map(|b| b.to_vec()).unwrap_or_default();" - )]; - } - if method == wap::CONTENT_STRING { - return vec![format!( - "{indent}let {name} = {node_var}.content_str().unwrap_or_default().to_string();" - )]; - } - if method == wap::CONTENT_INT { - return vec![format!( - "{indent}let {name} = {node_var}.content_str().and_then(|s| s.parse().ok()).unwrap_or_default();" + "{indent}let {name} = {node_var}.{};", + content_decoder(method) )]; } if !wap::is_attr_method(method) { return Vec::new(); } - let optional = wap::is_optional_method(method); + // See `rust_field_type`: the accessor spelling and the IR's `required` are both + // sources of optionality, and the two must agree or the initializer will not match the + // declared field type. + let optional = wap::is_optional_method(method) || !f.required; match wap::method_field_type(method) { ParsedFieldType::Integer if optional => vec![format!( "{indent}let {name} = {node_var}.get_attr({flit}).and_then(|v| v.as_str().parse().ok());" @@ -68,6 +65,12 @@ pub(crate) fn emit_field_parse(f: &ParsedField, node_var: &str, indent: &str) -> format!("{indent} .as_str()"), format!("{indent} .parse()?;"), ], + // An OPTIONAL JID must come first: `rust_field_type` declares `Option` for a + // `maybeAttr…Jid`, and falling into the branch below both mis-typed the + // initializer and rejected the absence the accessor exists to permit. + t if t.is_jid() && optional => vec![format!( + "{indent}let {name} = {node_var}.get_attr({flit}).and_then(|v| v.to_jid());" + )], // Every JID flavor materializes as one `Jid`; switch on `is_jid()` so a newly // preserved flavor (UserJid/LidUserJid/…) is parsed as a JID, not a String. t if t.is_jid() => vec![format!( @@ -85,6 +88,26 @@ pub(crate) fn emit_field_parse(f: &ParsedField, node_var: &str, indent: &str) -> } } +/// How to read a content leaf off a node, as a full expression yielding the field's type. +/// +/// `contentInt()` and `contentUint(N)` are BOTH integers and are decoded completely +/// differently: `contentInt` is decimal text (a follower count), while `contentUint(N)` +/// is N big-endian bytes (a 3-byte prekey id, a 4-byte registration id). Reading the +/// latter as text makes every one of them silently `0`, which is what grouping them by +/// `method_field_type` alone did. +pub(crate) fn content_decoder(method: &str) -> &'static str { + if method == "contentUint" { + return "content_bytes()\n .map(|b| b.iter().fold(0u64, |acc, &x| (acc << 8) | x as u64))\n .unwrap_or_default()"; + } + match wap::method_field_type(method) { + ParsedFieldType::Bytes => "content_bytes().map(|b| b.to_vec()).unwrap_or_default()", + ParsedFieldType::Integer => { + "content_str().and_then(|s| s.parse().ok()).unwrap_or_default()" + } + _ => "content_str().unwrap_or_default().to_string()", + } +} + /// Emit the body of `parse_response`, ending with `Ok( {{ ... }})`. pub(crate) fn emit_response_parser( fields: &[ParsedField], @@ -269,16 +292,43 @@ fn emit_struct_reads( indent, ); let lit = rust_lit(tag); - let bytes = ct == wa_ir::ContentType::Bytes; + // Two spellings per kind: one that yields an `Option` for the `maybeChild` + // chain, one that unwraps for the required branch. Kept as literal text per + // kind so adding the integer reading leaves the existing bytes/string output + // byte-for-byte unchanged. + // + // The child's OWN accessor decides when it has one, because `ContentType` + // cannot tell decimal text from big-endian bytes: `contentInt` and + // `contentUint` are both `Integer` and decode oppositely. + let leaf_method = children_of(f) + .iter() + .map(|c| c.method.as_str()) + .find(|m| wap::is_content_method(m)); + let (opt_read, req_read) = match leaf_method { + Some("contentUint") => ( + "content_bytes().map(|b| b.iter().fold(0u64, |acc, &x| (acc << 8) | x as u64))", + "content_bytes()\n .map(|b| b.iter().fold(0u64, |acc, &x| (acc << 8) | x as u64))\n .unwrap_or_default()", + ), + _ => match ct { + wa_ir::ContentType::Bytes => ( + "content_bytes().map(|b| b.to_vec())", + "content_bytes().map(|b| b.to_vec()).unwrap_or_default()", + ), + wa_ir::ContentType::Integer => ( + "content_str().and_then(|s| s.parse().ok())", + "content_str().and_then(|s| s.parse().ok()).unwrap_or_default()", + ), + _ => ( + "content_str().map(|s| s.to_string())", + "content_str().unwrap_or_default().to_string()", + ), + }, + }; if f.method == "maybeChild" { lines.push(format!( "{indent}let {id} = {base}.get_optional_child({lit})" )); - lines.push(if bytes { - format!("{indent} .and_then(|n| n.content_bytes().map(|b| b.to_vec()));") - } else { - format!("{indent} .and_then(|n| n.content_str().map(|s| s.to_string()));") - }); + lines.push(format!("{indent} .and_then(|n| n.{opt_read});")); } else { lines.push(format!( "{indent}let {id}_node = {base}.get_optional_child({lit})" @@ -287,11 +337,7 @@ fn emit_struct_reads( "{indent} .ok_or_else(|| anyhow::anyhow!(\"missing <{}>\"))?;", rust_lit_inner(tag) )); - lines.push(if bytes { - format!("{indent}let {id} = {id}_node.content_bytes().map(|b| b.to_vec()).unwrap_or_default();") - } else { - format!("{indent}let {id} = {id}_node.content_str().unwrap_or_default().to_string();") - }); + lines.push(format!("{indent}let {id} = {id}_node.{req_read};")); } inits.push(format!("{indent} {id},")); continue; diff --git a/crates/wa-codegen/src/fields.rs b/crates/wa-codegen/src/fields.rs index a1a0b3e..72137c7 100644 --- a/crates/wa-codegen/src/fields.rs +++ b/crates/wa-codegen/src/fields.rs @@ -89,7 +89,13 @@ pub(crate) fn rust_field_type(field: &ParsedField) -> &'static str { // String / Enum / (Bool/Union handled elsewhere) materialize as String. _ => "String", }; - if wap::is_optional_method(&field.method) { + // Optionality has TWO sources. The accessor spelling is one; the IR's own `required` + // is the other, and it is the only one that sees a smax tail conditional making a + // field optional without changing its accessor. 108 JID fields in the committed + // artifact are `attrUserJid` with `required: false`, and deriving from the name alone + // declared them `Jid` and emitted `ok_or_else("missing …")` — rejecting responses the + // IR explicitly says may omit them. + if wap::is_optional_method(&field.method) || !field.required { match base { "u64" => "Option", "Vec" => "Option>", @@ -123,14 +129,17 @@ pub(crate) fn is_child_field(f: &ParsedField) -> bool { } /// A field the codegen materializes as a top-level attr-style field: an attribute -/// accessor (via [`wap::is_attr_method`]), a `contentBytes` leaf, or a `hasAttr` -/// presence marker (the latter filtered out by callers before emission). +/// accessor (via [`wap::is_attr_method`]), **any** content leaf (via +/// [`wap::is_content_method`]), or a `hasAttr` presence marker (the latter filtered out +/// by callers before emission). +/// +/// The content half is derived, not enumerated. Naming three spellings here was the +/// fourth site of that mistake in this change, and the most misleading: the scanners +/// recovered live `contentUint` fields, the IR carried them, and the reference codegen +/// dropped them on the floor — so the generated Rust came out byte-identical and the +/// unchanged output read as "nothing broke" rather than "the new data is being ignored". pub(crate) fn is_attr_field(f: &ParsedField) -> bool { - wap::is_attr_method(&f.method) - || f.method == wap::CONTENT_BYTES - || f.method == wap::CONTENT_STRING - || f.method == wap::CONTENT_INT - || f.method == wap::HAS_ATTR + wap::is_attr_method(&f.method) || wap::is_content_method(&f.method) || f.method == wap::HAS_ATTR } /// If `f` is a `child`/`maybeChild` whose body is just a content accessor @@ -145,15 +154,31 @@ pub(crate) fn child_content_type(f: &ParsedField) -> Option { if kids.is_empty() || !kids.iter().all(is_content_method) { return None; } - Some(if kids.iter().any(|c| c.method == wap::CONTENT_BYTES) { - ContentType::Bytes - } else { - ContentType::String - }) + // Bytes wins a mixed group (the widest reading); otherwise the kids' own decoded + // type decides. Collapsing everything that was not bytes onto `String` is what made + // ``, `` and `` — three `contentUint` siblings — share a + // single generated `content` field, two of the three silently dropped. + // + // Both branches ask the classifier. Using it for integers and an exact `contentBytes` + // name test for bytes — in the same expression — would have typed a + // `contentBytesRange` child as `String` and read it with `content_str()`. + let decodes_to = |c: &ParsedField| wap::method_field_type(&c.method); + Some( + if kids.iter().any(|c| decodes_to(c) == ParsedFieldType::Bytes) { + ContentType::Bytes + } else if kids + .iter() + .all(|c| decodes_to(c) == ParsedFieldType::Integer) + { + ContentType::Integer + } else { + ContentType::String + }, + ) } fn is_content_method(f: &ParsedField) -> bool { - f.method == wap::CONTENT_STRING || f.method == wap::CONTENT_BYTES + wap::is_content_method(&f.method) } fn children_of(f: &ParsedField) -> &[ParsedField] { @@ -253,10 +278,10 @@ pub(crate) fn collect_response_fields( // `child("x").contentString()` → a single `x: String` field (named by // the child tag), not a stray `content` attr that collapses siblings. if let Some(ct) = f.content_type.or_else(|| child_content_type(f)) { - let base = if ct == ContentType::Bytes { - "Vec" - } else { - "String" + let base = match ct { + ContentType::Bytes => "Vec", + ContentType::Integer => "u64", + _ => "String", }; let wrapped = if f.method == "maybeChild" { format!("Option<{base}>") diff --git a/crates/wa-codegen/src/lib.rs b/crates/wa-codegen/src/lib.rs index d1a1b07..81cebb0 100644 --- a/crates/wa-codegen/src/lib.rs +++ b/crates/wa-codegen/src/lib.rs @@ -318,6 +318,175 @@ mod tests { assert!(c.contains("let body = body_node.content_str().unwrap_or_default().to_string();")); } + #[test] + fn integer_content_children_get_their_own_named_fields() { + // Two things were wrong at once, and the second hid the first: the codegen's + // content predicate admitted only three spellings, so live `contentUint` fields + // were dropped and the generated Rust came out unchanged — which read as "nothing + // broke". Once they arrived, every one of them was named `content` and collapsed + // into a single field, so two of three values were still lost. + let uint_child = |tag: &str| { + let mut c = parsed("child", tag, ParsedFieldType::String); + c.tag = Some(tag.into()); + c.children = Some(vec![parsed( + "contentUint", + "content", + ParsedFieldType::Integer, + )]); + c + }; + let ir = IqIr { + wa_version: "0.0.0".into(), + stanzas: vec![IqStanzaDef { + module_name: "WAWebDigest".into(), + namespace: "encrypt".into(), + iq_type: IqType::Get, + target: IqTarget::Server, + parser_name: "p".into(), + exported_function: Some("digest".into()), + all_exports: vec!["digest".into()], + request: IqRequestDef { + namespace: "encrypt".into(), + iq_type: IqType::Get, + target: IqTarget::Server, + children: vec![], + }, + response: ParsedResponse { + parser_name: "p".into(), + assertions: vec![], + fields: vec![uint_child("registration"), uint_child("id")], + ..Default::default() + }, + }], + unparseable: vec![], + }; + let c = &generate_iq(&ir); + assert!(c.contains("pub registration: u64,"), "registration field"); + assert!(c.contains("pub id: u64,"), "id field"); + assert!( + !c.contains("pub content: u64,"), + "must not collapse both onto `content`" + ); + // The accessor reads N big-endian bytes, not decimal text — a 3-byte prekey id, + // a 4-byte registration id. Parsing that as a string makes every one silently 0. + assert!( + c.contains("content_bytes()") && c.contains("(acc << 8) | x as u64"), + "and the value is decoded big-endian:\n{c}" + ); + } + + #[test] + fn an_optional_jid_parses_optionally() { + // `rust_field_type` declares `Option` for a `maybeAttr…Jid`, but every JID + // went through the unconditional branch — a `Jid` initializer for an + // `Option` field, which also rejects the absence the accessor permits. + let ir = IqIr { + wa_version: "0.0.0".into(), + stanzas: vec![IqStanzaDef { + module_name: "WAWebPn".into(), + namespace: "w:g2".into(), + iq_type: IqType::Get, + target: IqTarget::Server, + parser_name: "p".into(), + exported_function: Some("pn".into()), + all_exports: vec!["pn".into()], + request: IqRequestDef { + namespace: "w:g2".into(), + iq_type: IqType::Get, + target: IqTarget::Server, + children: vec![], + }, + response: ParsedResponse { + parser_name: "p".into(), + assertions: vec![], + fields: vec![ + parsed( + "maybeAttrPhoneUserJid", + "participant_pn", + ParsedFieldType::UserJid, + ), + // Optional by the IR, NOT by the accessor spelling: a smax tail + // conditional makes a field optional without renaming its + // accessor, and 108 such JID fields are live in the artifact. + ParsedField { + required: false, + ..parsed("attrUserJid", "to", ParsedFieldType::UserJid) + }, + ], + ..Default::default() + }, + }], + unparseable: vec![], + }; + let c = &generate_iq(&ir); + assert!( + c.contains("pub participant_pn: Option,"), + "declared optional:\n{c}" + ); + assert!( + !c.contains("missing participant_pn"), + "and never required in the parser:\n{c}" + ); + assert!( + c.contains("pub to: Option,"), + "`required: false` alone is enough to make it optional:\n{c}" + ); + assert!( + !c.contains("missing to"), + "so the parser never demands it:\n{c}" + ); + assert!( + c.contains(".and_then(|v| v.to_jid());"), + "parsed as an optional Jid:\n{c}" + ); + } + + #[test] + fn a_ranged_byte_content_child_is_still_bytes() { + // `child("blob").contentBytesRange(1, 128)` decodes to bytes. Asking the + // classifier for the integer branch while testing the exact name `contentBytes` + // for the bytes branch — in one expression — typed this as `String` and read it + // with `content_str()`, so a byte payload came out as lossy text. + let mut blob = parsed("child", "blob", ParsedFieldType::String); + blob.tag = Some("blob".into()); + blob.children = Some(vec![parsed( + "contentBytesRange", + "content", + ParsedFieldType::Bytes, + )]); + let ir = IqIr { + wa_version: "0.0.0".into(), + stanzas: vec![IqStanzaDef { + module_name: "WAWebBlob".into(), + namespace: "encrypt".into(), + iq_type: IqType::Get, + target: IqTarget::Server, + parser_name: "p".into(), + exported_function: Some("blob".into()), + all_exports: vec!["blob".into()], + request: IqRequestDef { + namespace: "encrypt".into(), + iq_type: IqType::Get, + target: IqTarget::Server, + children: vec![], + }, + response: ParsedResponse { + parser_name: "p".into(), + assertions: vec![], + fields: vec![blob], + ..Default::default() + }, + }], + unparseable: vec![], + }; + let c = &generate_iq(&ir); + assert!(c.contains("pub blob: Vec,"), "typed as bytes:\n{c}"); + assert!( + c.contains("blob_node.content_bytes()"), + "and read as bytes:\n{c}" + ); + } + #[test] fn generates_spec_with_request_and_response() { let ir = IqIr { diff --git a/crates/wa-codegen/src/notif_export.rs b/crates/wa-codegen/src/notif_export.rs index dbeec1e..862454f 100644 --- a/crates/wa-codegen/src/notif_export.rs +++ b/crates/wa-codegen/src/notif_export.rs @@ -9,7 +9,7 @@ use wa_ir::{NotifIr, NotificationDef, StanzaTagDef}; use crate::fields::{RustChildStruct, RustField, collect_response_fields, emit_enum_def}; -use crate::naming::{pascal_case, snake_case}; +use crate::naming::{pascal_case, rust_lit, snake_case}; /// Generate the reference Rust catalog from the notification IR. pub fn generate_notif(ir: &NotifIr) -> String { @@ -17,6 +17,7 @@ pub fn generate_notif(ir: &NotifIr) -> String { body.push_str(&emit_notification_type_enum(&ir.notifications)); body.push_str(&emit_stanza_tag_enum(&ir.stanza_tags)); body.push_str(&emit_handler_table(&ir.notifications)); + body.push_str(&emit_action_tables(&ir.notifications)); let (content, uses_jid) = emit_content_module(&ir.notifications); let mut out = String::new(); @@ -266,6 +267,221 @@ fn opt_str(v: &Option) -> String { } } +/// The `NotifFieldType` variants, in IR order. +/// +/// Paired with [`field_type_variant`]'s exhaustive match: adding a variant to +/// [`wa_ir::ParsedFieldType`] fails to compile the generator rather than silently +/// widening a generated enum that a consumer has already matched on. +const FIELD_TYPE_VARIANTS: &[&str] = &[ + "String", + "Integer", + "Timestamp", + "TimestampMillis", + "Enum", + "Bytes", + "Jid", + "UserJid", + "LidUserJid", + "DeviceJid", + "LidDeviceJid", + "GroupJid", + "NewsletterJid", + "CallJid", + "BroadcastJid", + "StatusJid", + "JidTyped", + "Bool", + "Union", +]; + +/// The generated variant name for an IR field type. Exhaustive on purpose; see +/// [`FIELD_TYPE_VARIANTS`]. +fn field_type_variant(t: wa_ir::ParsedFieldType) -> &'static str { + use wa_ir::ParsedFieldType as T; + match t { + T::String => "String", + T::Integer => "Integer", + T::Timestamp => "Timestamp", + T::TimestampMillis => "TimestampMillis", + T::Enum => "Enum", + T::Bytes => "Bytes", + T::Jid => "Jid", + T::UserJid => "UserJid", + T::LidUserJid => "LidUserJid", + T::DeviceJid => "DeviceJid", + T::LidDeviceJid => "LidDeviceJid", + T::GroupJid => "GroupJid", + T::NewsletterJid => "NewsletterJid", + T::CallJid => "CallJid", + T::BroadcastJid => "BroadcastJid", + T::StatusJid => "StatusJid", + T::JidTyped => "JidTyped", + T::Bool => "Bool", + T::Union => "Union", + } +} + +/// The payload action unions (`notifications[].actions`) as a const table. +/// +/// The envelope structs above describe what wraps the payload; this is the layer INSIDE +/// it — `w:gp2`'s 47 group-action arms and their normalization. Without it a consumer +/// reading the reference `notif.rs` instead of the JSON sees none of it, which is the +/// whole point of shipping a reference consumer. +/// +/// Emitted as data rather than a generated enum per notification type: the arms are a +/// many-to-one wire-tag → action-type map with heterogeneous payloads, and a table keeps +/// the mapping and the per-arm shape addressable without inventing 47 struct names. +fn emit_action_tables(notifications: &[NotificationDef]) -> String { + if notifications.iter().all(|n| n.actions.is_empty()) { + return String::new(); + } + let mut l = String::new(); + l.push_str( + "/// How an action field decodes. Mirrors the IR's own vocabulary rather than\n\ + /// collapsing to a Rust type, because the JID flavours must stay distinct: a PN\n\ + /// user JID and a LID user JID are different identities for the same person.\n", + ); + l.push_str("#[derive(Debug, Clone, Copy, PartialEq, Eq)]\n"); + l.push_str("pub enum NotifFieldType {\n"); + for v in FIELD_TYPE_VARIANTS { + l.push_str(&format!(" {v},\n")); + } + l.push_str("}\n\n"); + l.push_str("/// One field an action arm reads off its child element.\n"); + l.push_str("#[derive(Debug, Clone, Copy)]\n"); + l.push_str("pub struct NotifActionField {\n"); + l.push_str(" /// Output field name.\n"); + l.push_str(" pub name: &'static str,\n"); + l.push_str(" /// The wire attribute (or child tag, for a content read) it comes from.\n"); + l.push_str(" pub wire_name: &'static str,\n"); + l.push_str(" /// How the value decodes.\n"); + l.push_str(" pub field_type: NotifFieldType,\n"); + l.push_str(" /// Whether the arm reads it unconditionally.\n"); + l.push_str(" pub required: bool,\n"); + l.push_str(" /// The element body is read instead of an attribute.\n"); + l.push_str(" pub content: bool,\n"); + l.push_str( + " /// The wire enum the handler validates this value against, when the\n\ + \x20 /// extractor could name it. A `field_type` of `Enum` says the value is\n\ + \x20 /// constrained; this says to WHAT.\n", + ); + l.push_str(" pub enum_values: &'static [&'static str],\n"); + l.push_str("}\n\n"); + l.push_str( + "/// A value an arm stamps rather than reading. Typed, because `false` and the\n\ + /// string `\"false\"` are different values and a stringified table cannot say which.\n", + ); + l.push_str("#[derive(Debug, Clone, Copy)]\n"); + l.push_str("pub enum NotifConstValue {\n"); + l.push_str(" Bool(bool),\n"); + l.push_str(" Int(i64),\n"); + l.push_str(" Str(&'static str),\n"); + l.push_str("}\n\n"); + l.push_str("/// A repeated sub-element an arm maps over (`participants`).\n"); + l.push_str("#[derive(Debug, Clone, Copy)]\n"); + l.push_str("pub struct NotifActionChild {\n"); + l.push_str(" pub name: &'static str,\n"); + l.push_str(" pub wire_tag: &'static str,\n"); + l.push_str(" pub fields: &'static [NotifActionField],\n"); + l.push_str("}\n\n"); + l.push_str("/// One arm of a notification's payload action union.\n"); + l.push_str("#[derive(Debug, Clone, Copy)]\n"); + l.push_str("pub struct NotifAction {\n"); + l.push_str(" pub notif_type: NotificationType,\n"); + l.push_str(" /// The child element's tag — what the handler switches on.\n"); + l.push_str(" pub wire_tag: &'static str,\n"); + l.push_str( + " /// The normalized identity. NOT always the wire tag (`not_ephemeral` →\n\ + \x20 /// `ephemeral`); `None` when the arm computes it.\n", + ); + l.push_str(" pub action_type: Option<&'static str>,\n"); + l.push_str(" pub fields: &'static [NotifActionField],\n"); + l.push_str( + " /// Fields the arm stamps to a constant rather than reading — the\n\ + \x20 /// normalization that is invisible from the wire alone.\n", + ); + l.push_str(" pub constants: &'static [(&'static str, NotifConstValue)],\n"); + l.push_str(" pub children: &'static [NotifActionChild],\n"); + l.push_str("}\n\n"); + + let field_list = |fields: &[wa_ir::NotifActionField]| -> String { + let items: Vec = fields + .iter() + .map(|f| { + let values: Vec = f + .enum_ref + .as_ref() + .map(|e| e.variants.iter().map(|v| rust_lit(&v.value)).collect()) + .unwrap_or_default(); + format!( + "NotifActionField {{ name: {}, wire_name: {}, field_type: NotifFieldType::{}, required: {}, content: {}, enum_values: &[{}] }}", + rust_lit(&f.name), + rust_lit(&f.wire_name), + field_type_variant(f.field_type), + f.required, + f.content, + values.join(", ") + ) + }) + .collect(); + format!("&[{}]", items.join(", ")) + }; + + l.push_str("/// Every payload action arm, by notification type then wire tag.\n"); + l.push_str("pub const NOTIF_ACTIONS: &[NotifAction] = &[\n"); + for n in notifications { + for a in &n.actions { + let constants: Vec = a + .constant_fields + .iter() + .map(|c| { + let v = match &c.value { + wa_ir::NotifConstValue::Bool(b) => format!("NotifConstValue::Bool({b})"), + wa_ir::NotifConstValue::Int(i) => format!("NotifConstValue::Int({i})"), + wa_ir::NotifConstValue::Str(s) => { + format!("NotifConstValue::Str({})", rust_lit(s)) + } + }; + format!("({}, {v})", rust_lit(&c.name)) + }) + .collect(); + let children: Vec = a + .children + .iter() + .map(|c| { + format!( + "NotifActionChild {{ name: {}, wire_tag: {}, fields: {} }}", + rust_lit(&c.name), + rust_lit(&c.wire_tag), + field_list(&c.fields) + ) + }) + .collect(); + l.push_str(&format!( + " NotifAction {{ notif_type: NotificationType::{}, wire_tag: {}, \ + action_type: {}, fields: {}, constants: &[{}], children: &[{}] }},\n", + pascal_case(&n.notif_type), + rust_lit(&a.wire_tag), + match &a.action_type { + Some(t) => format!("Some({})", rust_lit(t)), + None => "None".to_string(), + }, + field_list(&a.fields), + constants.join(", "), + children.join(", ") + )); + } + } + l.push_str("];\n\n"); + l.push_str( + "/// The arms a notification type's payload can carry.\n\ + pub fn actions_for(t: NotificationType) -> impl Iterator {\n\ + \x20 NOTIF_ACTIONS.iter().filter(move |a| a.notif_type == t)\n\ + }\n\n", + ); + l +} + #[cfg(test)] mod tests { use super::*; @@ -274,6 +490,39 @@ mod tests { SubDiscriminant, SubDiscriminantOn, }; + #[test] + fn the_payload_action_union_reaches_generated_rust() { + // The envelope structs describe what WRAPS the payload; the arms inside it are a + // whole protocol layer, and a consumer reading this file instead of the JSON saw + // none of it. The many-to-one normalization is the part that cannot be guessed + // from the wire, so it is what the assertion pins. + let mut ir = ir(); + ir.notifications[0].actions = vec![wa_ir::NotifActionDef { + wire_tag: "not_ephemeral".into(), + action_type: Some("ephemeral".into()), + fields: vec![], + constant_fields: vec![wa_ir::NotifActionConstant { + name: "duration".into(), + value: wa_ir::NotifConstValue::Int(0), + }], + children: vec![], + }]; + let src = generate_notif(&ir); + assert!(src.contains("pub const NOTIF_ACTIONS"), "the table exists"); + assert!( + src.contains(r#"wire_tag: "not_ephemeral""#) + && src.contains(r#"action_type: Some("ephemeral")"#), + "the many-to-one mapping survives:\n{src}" + ); + // Typed, not stringified: `false` and the string `"false"` are different values, + // and a `(&str, &str)` table cannot say which one the arm stamps. + assert!( + src.contains(r#"("duration", NotifConstValue::Int(0))"#), + "and the constant the arm stamps, with its type:\n{src}" + ); + syn::parse_file(&src).expect("generated notif.rs is valid Rust"); + } + fn ir() -> NotifIr { NotifIr { wa_version: "2.3000.test".into(), @@ -295,6 +544,7 @@ mod tests { kind: AssertionKind::Tag, name: Some("notification".into()), value: None, + reference_path: None, }], fields: vec![ParsedField { method: "attrString".into(), @@ -305,6 +555,7 @@ mod tests { }], ..Default::default() }), + actions: Vec::new(), }, NotificationDef { notif_type: "encrypt".into(), @@ -319,6 +570,7 @@ mod tests { }], }], content: None, + actions: Vec::new(), }, ], } diff --git a/crates/wa-codegen/src/spec.rs b/crates/wa-codegen/src/spec.rs index 47eda68..02f3cfa 100644 --- a/crates/wa-codegen/src/spec.rs +++ b/crates/wa-codegen/src/spec.rs @@ -13,12 +13,20 @@ use wa_ir::{ /// to DIFFERENT literal values (`type:"result"` vs `type:"error"`): a response /// satisfying one fails the other's guard, so neither can shadow the other. pub(crate) fn assertions_conflict(a: &ResponseVariant, b: &ResponseVariant) -> bool { + // BOTH sides must pin a literal, and to the same NAMED attribute. `Some("result")` + // against a presence-only assertion (`value: None`) is not a conflict: a parser that + // merely requires `type` to exist also accepts `type="result"`, so the variants are + // not disjoint and the earlier arm shadows the later one in a first-success cascade. a.assertions.iter().any(|x| { x.kind == AssertionKind::Attr + && x.name.is_some() && x.value.is_some() - && b.assertions - .iter() - .any(|y| y.kind == AssertionKind::Attr && y.name == x.name && y.value != x.value) + && b.assertions.iter().any(|y| { + y.kind == AssertionKind::Attr + && y.name == x.name + && y.value.is_some() + && y.value != x.value + }) }) } @@ -339,7 +347,10 @@ fn emit_success_guards(op: &IqStanzaDef, indent: &str) -> Vec { } } // Tag (the `` root) / FromServer are not success-vs-error discriminators. - AssertionKind::Tag | AssertionKind::FromServer => {} + // Neither is a Reference echo (`from` == the request's `to`): every outcome + // of the same request satisfies it identically, so it separates nothing — + // it is a request-correlation rule, enforced by whoever holds the request. + AssertionKind::Tag | AssertionKind::FromServer | AssertionKind::Reference => {} } } lines @@ -764,6 +775,37 @@ mod tests { use super::*; use wa_ir::{IqRequestDef, ParsedResponse}; + fn conflict_attr(name: &str, value: Option<&str>) -> wa_ir::ResponseAssertion { + wa_ir::ResponseAssertion { + kind: AssertionKind::Attr, + name: Some(name.to_string()), + value: value.map(str::to_string), + reference_path: None, + } + } + + fn conflict_variant(assertions: Vec) -> wa_ir::ResponseVariant { + wa_ir::ResponseVariant { + assertions, + ..Default::default() + } + } + + #[test] + fn a_presence_only_assertion_does_not_conflict_with_a_pin() { + // A parser that merely requires `type` to EXIST also accepts `type="result"`, so + // the two variants are not disjoint. Treating `Some("result") != None` as a + // conflict let the separability gate emit a first-success cascade whose earlier + // arm shadows the later one. + let pinned = conflict_variant(vec![conflict_attr("type", Some("result"))]); + let present = conflict_variant(vec![conflict_attr("type", None)]); + assert!(!assertions_conflict(&pinned, &present)); + assert!(!assertions_conflict(&present, &pinned)); + // Two different pins on the same attribute still conflict. + let other = conflict_variant(vec![conflict_attr("type", Some("error"))]); + assert!(assertions_conflict(&pinned, &other)); + } + fn stanza(module: &str, exported: Option<&str>) -> IqStanzaDef { IqStanzaDef { module_name: module.into(), @@ -836,8 +878,10 @@ mod tests { kind: AssertionKind::Attr, name: Some("type".into()), value: Some("result".into()), + reference_path: None, }], fields: vec![], + ..Default::default() }]; let guards = emit_success_guards(&s, " "); assert_eq!(guards.len(), 1); @@ -874,6 +918,7 @@ mod tests { kind: ResponseVariantKind::Success, assertions: vec![], fields: vec![attr("token")], + ..Default::default() }, ResponseVariant { tag: "GetThingResponseError".into(), @@ -881,6 +926,7 @@ mod tests { kind: ResponseVariantKind::Error, assertions: vec![], fields: vec![attr("code")], + ..Default::default() }, ], ..Default::default() @@ -930,6 +976,7 @@ mod tests { kind: AssertionKind::Attr, name: Some("type".into()), value: Some(value.into()), + reference_path: None, } } // Success and error read the same field (`type`) — a bare subset that WOULD be @@ -945,6 +992,7 @@ mod tests { kind: ResponseVariantKind::Success, assertions: vec![type_assert("result")], fields: vec![attr("type")], + ..Default::default() }, ResponseVariant { tag: "GetThingResponseError".into(), @@ -952,6 +1000,7 @@ mod tests { kind: ResponseVariantKind::Error, assertions: vec![type_assert("error")], fields: vec![attr("type")], + ..Default::default() }, ], ..Default::default() @@ -1000,6 +1049,7 @@ mod tests { kind: ResponseVariantKind::Success, assertions: vec![], fields: vec![attr("type")], + ..Default::default() }, ResponseVariant { tag: "GetThingResponseError".into(), @@ -1007,6 +1057,7 @@ mod tests { kind: ResponseVariantKind::Error, assertions: vec![], fields: vec![attr("type")], + ..Default::default() }, ], ..Default::default() diff --git a/crates/wa-codegen/src/union.rs b/crates/wa-codegen/src/union.rs index 83acd2d..1577f85 100644 --- a/crates/wa-codegen/src/union.rs +++ b/crates/wa-codegen/src/union.rs @@ -704,20 +704,15 @@ fn value_payload(enum_name: &str, variant: &str, fields: &[ParsedField], node_va /// (the variant guard already proved the required attrs present). fn field_expr(f: &ParsedField, node_var: &str) -> String { let method = f.method.as_str(); - if method == wap::CONTENT_STRING { - return format!("{node_var}.content_str().unwrap_or_default().to_string()"); - } - if method == wap::CONTENT_BYTES { - return format!("{node_var}.content_bytes().map(|b| b.to_vec()).unwrap_or_default()"); - } - if method == wap::CONTENT_INT { - return format!( - "{node_var}.content_str().and_then(|s| s.parse().ok()).unwrap_or_default()" - ); + // Derived, not enumerated — the same three names were spelled out here as in + // `is_attr_field` and `child_content_type`, so a `contentUint` inside a union variant + // fell through to the attribute path and was read as an attribute that does not exist. + if wap::is_content_method(method) { + return format!("{node_var}.{}", crate::emit::content_decoder(method)); } let wire = f.wire_name.as_deref().unwrap_or(&f.name); let flit = rust_lit(wire); - let optional = wap::is_optional_method(method); + let optional = wap::is_optional_method(method) || !f.required; match wap::method_field_type(method) { ParsedFieldType::Integer if optional => { format!("{node_var}.get_attr({flit}).and_then(|v| v.as_str().parse().ok())") diff --git a/crates/wa-fetch/src/cache.rs b/crates/wa-fetch/src/cache.rs index ec9817a..f204f82 100644 --- a/crates/wa-fetch/src/cache.rs +++ b/crates/wa-fetch/src/cache.rs @@ -15,6 +15,14 @@ //! … //! ``` //! +//! The cache is **not** content-addressed, unlike the durable release store it can be +//! seeded from (`bundles--.tar.xz`). A cache filename is a *location* +//! label — the JS name comes from the URL's last segment, the wasm name is +//! `sha256(url)` — while the `sha256` recorded in `manifest.json` is the hash of the +//! **bytes**, and that is what integrity is checked against. Two hashes of different +//! things sit side by side here, so: the name never proves the content, the manifest +//! does. +//! //! JS and wasm live in **separate subtrees and separate manifest lists** on purpose: //! the JS set is concatenated into the source the extractors parse, so a wasm payload //! that leaked into that list would put megabytes of binary into it. [`BundleCache::check`] diff --git a/crates/wa-ir/src/iq.rs b/crates/wa-ir/src/iq.rs index f90553f..0deb266 100644 --- a/crates/wa-ir/src/iq.rs +++ b/crates/wa-ir/src/iq.rs @@ -255,6 +255,17 @@ pub enum AssertionKind { /// node, "admin_add")`) — a discriminator for marker union variants. The value is /// in [`ResponseAssertion::value`]; `name` is unused. Content, + /// The attribute named by [`ResponseAssertion::name`] must **echo a value taken + /// from the request** — `literal(attrString, node, "from", + /// attrStringFromReference(request, ["to"]))`. The expected value is not a + /// constant, so [`ResponseAssertion::value`] is absent; where it comes from is in + /// [`ResponseAssertion::reference_path`]. + /// + /// This is the rule 17 of the 26 namespace `IQError…Mixin`s (and every success + /// parser) enforce: an answer's `id` must equal the request's `id` and its `from` + /// the request's `to`. An emitter that hardcodes `from="s.whatsapp.net"` produces + /// stanzas a real client cannot parse whenever the request went to `g.us`. + Reference, } /// A single guard a response parser applies. @@ -267,6 +278,17 @@ pub struct ResponseAssertion { pub name: Option, #[serde(default, skip_serializing_if = "Option::is_none")] pub value: Option, + /// Where the expected value is read from **in the request**, for + /// [`AssertionKind::Reference`]. It is the argument list of WA's + /// `attrStringFromReference(request, path)` helper: every element but the last is a + /// child tag to descend into, and the last is the attribute name. So `["to"]` means + /// "the request's `to` attribute" and `["account", "action"]` means "the `action` + /// attribute of the request's `` child". + /// + /// Carried structurally (rather than left to be inferred from `name`) so a consumer + /// never has to pattern-match attribute names to know an echo rule applies. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub reference_path: Option>, } /// Scalar type a parsed response field decodes to. @@ -357,6 +379,13 @@ impl ParsedFieldType { pub enum ContentType { String, Bytes, + /// A decimal integer in the element body (`contentUint`, `contentInt`). Distinct + /// from [`String`] because a consumer that reads it as text has to re-parse, and + /// because collapsing it onto `String` is how three sibling integer contents ended + /// up sharing one generated field. + /// + /// [`String`]: ContentType::String + Integer, Nodes, } @@ -376,6 +405,24 @@ pub struct UnionVariant { pub assertions: Vec, } +/// Scanner-internal state for an enum accessor's allowed-value table, before the +/// cross-module post-pass runs. Never serialized — see [`ParsedField::pending_enum_ref`]. +/// +/// The unresolvable case is a *variant*, not an absence, so it can be counted. An enum +/// whose table the scan could not follow and a field that is simply not an enum must not +/// look alike: the first is a constraint we failed to extract and belongs in +/// `dropsByReason`, the second is nothing at all. +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum PendingEnum { + /// `o("Mod").ENUM` — a module export the bundle-wide index can finish resolving. + Link(AttrEnumRef), + /// A table that is not a structurally recoverable reference (a computed expression, + /// a runtime-composed set, an object literal with a non-literal member). A unit + /// variant: the reporting pass names the loss from the field's own `wireName`/`name`, + /// so there is nothing to carry here. + Unresolvable, +} + /// One field extracted from a response stanza by a parser. /// /// `method` is the parser accessor used (e.g. `attrString`, `maybeChild`, @@ -423,6 +470,77 @@ pub struct ParsedField { pub int_max: Option, #[serde(default, skip_serializing_if = "Option::is_none")] pub enum_keys: Option>, + /// The wire enum this field's value is drawn from, when the parser reads it with an + /// enum accessor (`attrStringEnum(node, "state", o("Mod").ENUM_OFF_ON)`). Resolved + /// the same way the request side resolves [`WapAttrDef::enum_ref`], so a consumer + /// can type the field as that enum instead of a bare string — and an emitter knows + /// which values are legal instead of guessing from the generated `ENUM_OFF_ON` name. + /// Absent when the enum argument is not a structurally resolvable module export, or + /// resolves to a non-string enum (never guessed). + /// + /// [`WapAttrDef::enum_ref`]: WapAttrDef::enum_ref + #[serde(default, skip_serializing_if = "Option::is_none")] + pub enum_ref: Option, + /// Scanner-internal: an enum reference seen but not yet resolved. + /// + /// The legacy scanner reads one module at a time and cannot follow `o("Mod").ENUM` + /// to its definition, so it records the *reference* here and a cross-module post-pass + /// promotes it into [`enum_ref`] once the whole bundle index exists. + /// + /// It is a separate field, and never serialized, because the pending state must not + /// be expressible in the published IR. It previously lived in [`enum_ref`] with an + /// empty `variants`, and the two callers that skipped the post-pass shipped exactly + /// that: `incoming/index.json` told consumers `ALL_NONE` and `STANZA_MSG_TYPES` admit + /// **no** legal value. Now a caller that forgets can only lose the link, never + /// publish a false one. + /// + /// [`enum_ref`]: ParsedField::enum_ref + #[serde(skip)] + #[cfg_attr(feature = "schema", schemars(skip))] + pub pending_enum_ref: Option, + /// The fixed value the parser pins this field to — `literal(attrString, participant, + /// "type", "admin")` → `"admin"`, `literal(attrInt, error, "code", 429)` → `"429"`. + /// Always the string form of the literal; [`field_type`] says how to read it (a + /// `code` field with `literalValue: "429"` is the integer 429 on the wire). On a + /// [`ParsedFieldType::Bytes`] field it is **lowercase hex** — the encoding + /// [`WapContent::const_bytes`] already uses on the request side — + /// and [`byte_length`] is its length: `contentLiteralBytes(node, new Uint8Array([5]))` + /// → `literalValue: "05"`, `byteLength: 1`. + /// + /// [`byte_length`]: ParsedField::byte_length + /// + /// [`required`] tells the two pinning forms apart, and the difference matters to an + /// emitter: a **required** literal (`literal`) is a hard discriminator — the + /// attribute MUST be present and equal to this value or the variant does not match; + /// an **optional** one (`optionalLiteral`) is pinned only when present — the emitter + /// may omit the attribute, but must never send a contradicting value. + /// + /// **On a [`ParsedFieldType::Bool`] field the pin is always conditional.** Such a + /// field is a *presence flag* — `{hasListCDhash: m.value != null}` — so its + /// `required: true` describes the flag (the parser always produces it), never the + /// wire attribute named by [`wire_name`], which by construction may be absent. The + /// pin constrains that attribute when present, and never the boolean itself. + /// + /// [`field_type`]: ParsedField::field_type + /// [`required`]: ParsedField::required + /// [`wire_name`]: ParsedField::wire_name + #[serde(default, skip_serializing_if = "Option::is_none")] + pub literal_value: Option, + /// The field is pinned not to a constant but to **a value taken from the request** — + /// the same echo rule [`AssertionKind::Reference`] carries, in the same + /// `attrStringFromReference` path form, but for a pin that is *not* a variant guard. + /// + /// A required echo (`literal(…, "from", ref.to)`) is recorded as an assertion, since + /// it must hold for the variant to match at all. An **optional** one + /// (`optionalLiteral(…, "c_dhash", ref.item.dhash)`) is not a guard — the attribute + /// may be absent — so it lives here instead: an emitter may omit it, but if it sends + /// it, the value must be the request's. Mutually exclusive with [`literal_value`], + /// and — like it — always conditional when carried on a [`ParsedFieldType::Bool`] + /// presence flag. + /// + /// [`literal_value`]: ParsedField::literal_value + #[serde(default, skip_serializing_if = "Option::is_none")] + pub reference_path: Option>, #[serde(default, skip_serializing_if = "Option::is_none")] pub tag: Option, #[serde(default, skip_serializing_if = "Option::is_none")] @@ -445,17 +563,87 @@ pub struct ParsedField { } /// How a response-root union variant classifies (drives codegen `Ok`/`Err` arms). +/// +/// The error side is split by **who is at fault**, because that decides what a caller +/// should do: a 4xx will fail again if retried unchanged, a 5xx may not. WA models the +/// two as separate parsers with disjoint code ranges (`bad-request` 400, +/// `rate-overlimit` 429, fallback 400–499 / `internal-server-error` 500, fallback +/// 500–599), so the split is the protocol's, not an interpretation. +/// +/// The side is derived from the **codes** the variant accepts, never from its name: WA +/// spells the arms inconsistently (`…ResponseServerError`, but also +/// `…ResponseInternalServerError`, and `SetResponsePreKeySuccessVnameFailure` reads as a +/// success while asserting `type="error"`). A variant whose codes are mixed or outside +/// both families stays [`Error`] — an error whose side could not be determined, which is +/// a fact worth stating rather than a coin flip. +/// +/// [`Error`]: ResponseVariantKind::Error #[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)] #[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] #[serde(rename_all = "snake_case")] pub enum ResponseVariantKind { #[default] Success, + /// The request was wrong (4xx) — retrying it unchanged will fail again. + ClientError, + /// The server failed (5xx) — the same request may succeed later. + ServerError, + /// An error whose side the accepted codes do not determine. Error, /// A structured non-happy outcome that still parses (Nack, Conflict, …). Alternative, } +impl ResponseVariantKind { + /// Whether this is any error outcome, whichever side is at fault. + pub fn is_error(&self) -> bool { + matches!( + self, + ResponseVariantKind::Error + | ResponseVariantKind::ClientError + | ResponseVariantKind::ServerError + ) + } +} + +/// One accepted `` shape of a response variant: the `code` and `text` that must +/// occur **together**. +/// +/// A variant accepting `400 bad-request` and `501 feature-not-implemented` cannot be +/// described by two independent lists — nothing would then rule out `400 +/// feature-not-implemented`, a combination the parser rejects, so an emitter picking one +/// value from each list produces an unparseable stanza. The pairing is the point. +/// +/// Every field is optional because each is a genuine shape: an arm may pin an exact +/// `(code, text)`, pin only the code and read the text freely +/// (`IQErrorReportTokenValidationFail` accepts any text with 548), or pin neither and +/// range-check the code (the `IQErrorFallback*` arms). +#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize)] +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] +#[serde(rename_all = "camelCase")] +pub struct ErrorArm { + /// The disjunction alternative this arm comes from (`IQErrorBadRequest`), when the + /// error is parsed as a `…Errors` union. `None` for an RPC that parses a single + /// `` child directly, which has exactly one arm and no name for it. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub name: Option, + /// The exact `code` this arm pins, when it pins one. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub code: Option, + /// The exact `text` this arm pins. Absent is a fact, not a gap — see the note above. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub text: Option, + /// Inclusive lower bound of the codes this arm accepts, when it range-checks instead + /// of pinning. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub code_min: Option, + /// Inclusive upper bound of the same range (see [`code_min`]). + /// + /// [`code_min`]: ErrorArm::code_min + #[serde(default, skip_serializing_if = "Option::is_none")] + pub code_max: Option, +} + /// One alternative of a response-root discriminated union (an `WASmaxInResponse` /// variant aggregated by the `WASmaxRPC` orchestrator). #[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize)] @@ -467,6 +655,34 @@ pub struct ResponseVariant { pub tag: String, pub module_name: String, pub kind: ResponseVariantKind, + /// The accepted `` shapes, in parser order — **which code goes with which + /// text**. See [`ErrorArm`]; this is the only representation of the vocabulary, + /// deliberately, because the flattened `errorCodes` / `errorTexts` lists it replaced + /// let an emitter combine one arm's code with another's text and produce a stanza no + /// branch accepts. + /// + /// An arm describes the *discriminating* `` node. When the variant also pins + /// the node above it, those pins are in [`error_envelope`], and the full shape is + /// **arm + envelope**. + /// + /// To answer "does this RPC accept code N / text T?", scan the arms — the question + /// the flat lists used to answer is one `.iter().any(…)` away, and asking it that way + /// cannot produce an invalid pair. + /// + /// [`error_envelope`]: ResponseVariant::error_envelope + #[serde(default, skip_serializing_if = "Vec::is_empty")] + pub error_arms: Vec, + /// Pins on the `` node **enclosing** the one the arms discriminate, for a + /// two-level error. + /// + /// `SetResponsePreKeySuccessVnameFailure` is the shape: `` — the + /// partial-failure envelope, shared by every arm — wrapping an inner `` whose + /// text the disjunction pins and whose code is range-checked. Pins are partitioned by + /// the node they are read from, so the envelope holds only the enclosing node's and + /// the inner node's shared constraints stay on the arms; mixing them would tell a + /// consumer that code 207 must also fall in 400–599. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub error_envelope: Option, pub assertions: Vec, pub fields: Vec, } @@ -486,6 +702,18 @@ pub struct ParsedResponse { pub fields: Vec, #[serde(default, skip_serializing_if = "Vec::is_empty")] pub variants: Vec, + /// Scanner-internal: constraints this parser carried that could not be resolved + /// structurally, as `dropsByReason` keys. Never serialized. + /// + /// The legacy scanner reads one module at a time and has no diagnostics channel of + /// its own, so it parks the losses on the shape it produces and whoever finishes the + /// shape drains them ([`crate::wap`]'s consumers do this via the response enum + /// linker). It exists for the same reason [`ParsedField::pending_enum_ref`] does: a + /// constraint seen and not recovered must never be indistinguishable from no + /// constraint at all. + #[serde(skip)] + #[cfg_attr(feature = "schema", schemars(skip))] + pub pending_drops: Vec, } // ─── IQ operation ──────────────────────────────────────────────────────────────── diff --git a/crates/wa-ir/src/lib.rs b/crates/wa-ir/src/lib.rs index bf87064..59042e8 100644 --- a/crates/wa-ir/src/lib.rs +++ b/crates/wa-ir/src/lib.rs @@ -62,7 +62,25 @@ pub enum Scalar { /// `waVersion` changes on every WhatsApp rollout; `schemaVersion` changes only /// when the *structure* of the IR changes. Consumers pin this to stay stable /// across WhatsApp updates. Bump on any breaking change to the IR shape. -pub const SCHEMA_VERSION: &str = "1.0.0"; +/// +/// # 2.0.0 — why the major bump +/// +/// Almost everything the validation-constraint work added is additive and optional +/// (`literalValue`, `referencePath`, `enumRef`, `errorArms`, `actions`, …), which a 1.x +/// consumer ignores. **One** change is not: [`AssertionKind`] gained a `reference` +/// variant, and that widens the value space of an *existing* field. +/// +/// A consumer with a closed enum — one generated from the 1.0 JSON Schema, or the Rust +/// enum itself — rejects the document rather than ignoring an unknown key. This is not +/// hypothetical: validating the current `iq/index.json` against the committed 1.0 schema +/// fails with 579 errors, all `'reference' is not valid under any of the given schemas`. +/// Publishing that as a minor bump would tell consumers the opposite of the truth. +/// +/// The migration is one variant wide: handle (or ignore) `kind: "reference"` on response +/// assertions. Everything else in 2.0.0 is opt-in. +/// +/// [`AssertionKind`]: crate::AssertionKind +pub const SCHEMA_VERSION: &str = "2.0.0"; /// Envelope that stamps a domain IR document with [`SCHEMA_VERSION`] at emit /// time, without altering the inner document's shape. diff --git a/crates/wa-ir/src/notif.rs b/crates/wa-ir/src/notif.rs index b765657..299bb02 100644 --- a/crates/wa-ir/src/notif.rs +++ b/crates/wa-ir/src/notif.rs @@ -120,6 +120,136 @@ pub struct NotificationDef { /// (it delegates to a job/sub-module) — the catalog entry still stands. #[serde(default, skip_serializing_if = "Option::is_none")] pub content: Option, + /// The payload **action union** carried inside the notification, when its handler + /// dispatches on the child tag (`w:gp2` and friends — see [`NotifActionDef`]). + /// [`content`] describes the envelope; this describes what is inside it. Empty for + /// a notification whose handler carries no such per-child-tag switch. + /// + /// [`content`]: NotificationDef::content + #[serde(default, skip_serializing_if = "Vec::is_empty")] + pub actions: Vec, +} + +/// One arm of a notification's payload action union: a child tag of the +/// `` and the fields the handler reads off it. +/// +/// WA Web parses these in a `switch (child.tag())` inside the handler (e.g. +/// `WAWebHandleGroupNotification`), where each arm returns an object stamped with an +/// `actionType`. Two facts there are invisible from the wire alone and cannot be +/// derived by a consumer: +/// +/// 1. **The mapping is many-to-one.** Several wire tags normalize onto one +/// `actionType` — `ephemeral` and `not_ephemeral` both become `ephemeral`, so a +/// consumer that branches on `not_ephemeral` is writing dead code. +/// 2. **Field names are rebound.** The disappearing-message timer arrives in the +/// `expiration` attribute but the action field is called `duration` (the *create* +/// payload's spelling, `ephemeralDuration`, belongs to a different shape) — reading +/// it under the wrong name silently yields 0. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] +#[serde(rename_all = "camelCase")] +pub struct NotifActionDef { + /// The child element's tag on the wire (`"ephemeral"`, `"not_ephemeral"`, + /// `"subject"`, …) — the value the handler switches on. + pub wire_tag: String, + /// The normalized action identity the handler stamps as `actionType`. **Not** always + /// equal to [`wire_tag`]: `not_ephemeral` maps to `ephemeral`, `locked`/`unlocked` + /// both map to `restrict`, and so on. `None` when the arm computes it dynamically + /// (e.g. `link` picks between three actions by its `link_type` attribute), which is + /// recorded rather than guessed. + /// + /// [`wire_tag`]: NotifActionDef::wire_tag + #[serde(default, skip_serializing_if = "Option::is_none")] + pub action_type: Option, + /// The fields the arm reads off the child node, in source order. + #[serde(default, skip_serializing_if = "Vec::is_empty")] + pub fields: Vec, + /// Output fields the arm sets to a **constant** rather than reading from the wire — + /// `not_ephemeral` sets `duration: 0`, `locked` sets `value: true`, `unlocked` + /// `value: false`. This is exactly the normalization that is invisible from the + /// stanza, and it is what makes the many-to-one tag mapping lossless: `ephemeral` + /// vs `not_ephemeral` differ only by this. Sorted by key for determinism. + #[serde(default, skip_serializing_if = "Vec::is_empty")] + pub constant_fields: Vec, + /// Repeated sub-elements the arm maps over (`revoke` → one entry per + /// ``), each with its own field list. + #[serde(default, skip_serializing_if = "Vec::is_empty")] + pub children: Vec, +} + +/// One field an action arm reads off the wire. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] +#[serde(rename_all = "camelCase")] +pub struct NotifActionField { + /// The output field name in the parsed action (`"duration"`). + pub name: String, + /// The wire attribute it is read from (`"expiration"`), or the child tag for a + /// content read. Differs from [`name`] often enough that assuming they match is the + /// bug this field exists to prevent. + /// + /// [`name`]: NotifActionField::name + pub wire_name: String, + /// How the value decodes, reusing the response-field type vocabulary. + #[serde(rename = "type")] + pub field_type: crate::ParsedFieldType, + /// Whether the arm reads the attribute unconditionally (`attrInt("expiration")`) or + /// guards on its presence (`hasAttr("reason") ? … : null`, `maybeAttrString`). + pub required: bool, + /// The element's text content is read instead of an attribute + /// (`child("body").contentString()`). + #[serde(default, skip_serializing_if = "std::ops::Not::not")] + pub content: bool, + /// The wire enum the value is validated against, when the arm reads it with an enum + /// accessor (`child.maybeAttrEnum("type", o("WAWebGroupApiConst").GROUP_PARTICIPANT_TYPES)`). + /// Without it a `"type": "enum"` field says the value is constrained but not to what, + /// which leaves a parser and an emitter guessing — the same gap `enumRef` closes on + /// the response side. + /// + /// Absent when the accessor validates against an **anonymous** lookup table declared + /// inline in the handler (`attrEnumOrNullIfUnknown("reason", v)` where `v` is a local + /// object literal). Such a table has no stable name — the identifier is whatever the + /// minifier picked this build — so naming it would churn the IR on every WhatsApp + /// rollout and invent an identity the bundle does not have. Reported as unresolved + /// rather than faked; recovering those value sets is a separate modelling question. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub enum_ref: Option, +} + +/// A `key → constant` pair an action arm stamps onto its result unconditionally. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] +#[serde(rename_all = "camelCase")] +pub struct NotifActionConstant { + pub name: String, + pub value: NotifConstValue, +} + +/// The value of a [`NotifActionConstant`] — the literal kinds a handler arm actually +/// stamps (`!0`/`!1`, `0`, a wire string). Deliberately narrower than [`crate::Scalar`] +/// (no float) so the notif IR stays `Eq`-comparable for the determinism checks. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] +#[serde(untagged)] +pub enum NotifConstValue { + Bool(bool), + Int(i64), + Str(String), +} + +/// A repeated sub-element an action arm maps over +/// (`mapChildrenWithTag("participant", …)`). +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] +#[serde(rename_all = "camelCase")] +pub struct NotifActionChild { + /// The output field the mapped list lands in (`"participants"`). + pub name: String, + /// The repeated element's wire tag (`"participant"`). + pub wire_tag: String, + /// The fields read off each element. + #[serde(default, skip_serializing_if = "Vec::is_empty")] + pub fields: Vec, } /// The incoming-dispatch IR document: version stamp + the dispatcher module name + @@ -150,6 +280,7 @@ mod tests { handler_function: Some("handleDevicesNotification".into()), sub_discriminants: vec![], content: None, + actions: vec![], }; let json = serde_json::to_value(&def).unwrap(); // `notif_type` serializes under the wire name `type`. diff --git a/crates/wa-ir/src/wap.rs b/crates/wa-ir/src/wap.rs index df73bcb..21f63ee 100644 --- a/crates/wa-ir/src/wap.rs +++ b/crates/wa-ir/src/wap.rs @@ -59,9 +59,23 @@ pub fn is_child_method(m: &str) -> bool { ) } -/// Content accessors (`contentString` / `contentBytes` / `contentInt`). +/// Content accessors — every spelling that reads the element's content rather than an +/// attribute, whatever it decodes to. The single source of truth for the question, so a +/// caller cannot recognise a subset: teaching [`method_field_type`] about `contentUint` +/// while a reader still whitelisted three spellings made those fields drop out entirely +/// instead of being typed. pub fn is_content_method(m: &str) -> bool { - matches!(m, CONTENT_STRING | CONTENT_BYTES | CONTENT_INT) + matches!( + m, + CONTENT_STRING + | CONTENT_BYTES + | CONTENT_INT + | "contentUint" + | "contentEnum" + | "contentStringEnum" + | "contentBytesRange" + | "contentLiteralBytes" + ) } /// The attribute value accessors (`attr*` / `maybeAttr*`, including the typed-JID @@ -70,33 +84,19 @@ pub fn is_content_method(m: &str) -> bool { /// is the single source of truth for "is this method an attribute accessor", /// shared by the scanner and the codegen so the two can't drift. pub fn is_attr_method(m: &str) -> bool { - matches!( - m, - ATTR_STRING - | ATTR_INT - | ATTR_ENUM - | ATTR_ENUM_VALUES - | MAYBE_ATTR_STRING - | MAYBE_ATTR_INT - | MAYBE_ATTR_ENUM - | ATTR_DEVICE_JID - | ATTR_GROUP_JID - | ATTR_JID_WITH_TYPE - | ATTR_TIME - | MAYBE_ATTR_TIME - | ATTR_USER_JID - | MAYBE_ATTR_USER_JID - | ATTR_WAP_JID - | ATTR_CHAT_JID - | ATTR_FROM_JID - | ATTR_LID_USER_JID - | MAYBE_ATTR_LID_USER_JID - | ATTR_LID_DEVICE_JID - | ATTR_NEWSLETTER_JID - | ATTR_CALL_JID - | ATTR_BROADCAST_JID - | ATTR_STATUS_JID - ) + // Derived from the spelling, not enumerated. Every accessor WA names `attr…` / + // `maybeAttr…` reads an attribute; `hasAttr` is the presence test, not a read, and + // the `…FromReference` helpers read off the REQUEST rather than the node. + // + // Enumerating was the bug: the list drifted from `method_field_type`, so giving a JID + // accessor its own name instead of collapsing it onto `attrJidWithType` silently + // dropped 85 lines of generated code — the fields fell outside the list and stopped + // being treated as attribute reads at all. + // `literalJid` is an attribute read too — it reads a JID attribute and pins it to a + // value — while `literalContent` pins the element's content and names no attribute. + let literal_attr = m.starts_with("literal") && !m.contains("Content"); + let attr = (m.starts_with("attr") || m.starts_with("maybeAttr")) && m != HAS_ATTR; + (attr || literal_attr) && !m.ends_with("FromReference") } /// `maybe*` accessors decode to optional / non-required fields. @@ -105,17 +105,42 @@ pub fn is_optional_method(m: &str) -> bool { } /// The scalar [`ParsedFieldType`] a response accessor decodes to. +/// +/// `maybeAttrX` is derived from `attrX` rather than enumerated beside it. The two decode +/// identically — the `maybe` spelling only tolerates absence — so listing both invites +/// exactly the bug that motivated this: `maybeAttrPhoneUserJid` was missing from the +/// table and reported a PN user JID as a bare `string`, the conflation this module's own +/// note calls protocol-safety-critical. Deriving means a flavour added to the table +/// covers both spellings, and one that is never added defaults visibly for both. pub fn method_field_type(m: &str) -> ParsedFieldType { + if let Some(rest) = m.strip_prefix("maybe") + && let Some(first) = rest.chars().next() + { + let attr: String = first.to_lowercase().chain(rest.chars().skip(1)).collect(); + return method_field_type(&attr); + } match m { - ATTR_STRING | MAYBE_ATTR_STRING | ATTR_ENUM | MAYBE_ATTR_ENUM | ATTR_ENUM_VALUES => { - ParsedFieldType::String + ATTR_STRING => ParsedFieldType::String, + // An enum accessor decodes to an enum, not a bare string. The smax side already + // types these `Enum` through its own normalizer, so mapping them to `String` here + // made one concept two types across domains — 486 fields said `enum` and 28 said + // `string` for the same accessors — and left an `enumRef` hanging off a field a + // consumer filtering on `type == "enum"` would never look at. + ATTR_ENUM | ATTR_ENUM_VALUES => ParsedFieldType::Enum, + // `attrFutureTime` range-checks a unix time it read with `attrInt`; `contentUint` + // decodes an unsigned integer out of the content bytes. + ATTR_INT | ATTR_TIME | "attrIntRange" | "attrFutureTime" | CONTENT_INT | "contentUint" => { + ParsedFieldType::Integer } - ATTR_INT | MAYBE_ATTR_INT | ATTR_TIME | MAYBE_ATTR_TIME => ParsedFieldType::Integer, // Each JID accessor pins the flavor (server/format) it validates. Keeping the // flavor — rather than collapsing to a bare `Jid` — is protocol-safety-critical: // a LID user JID and a PN user JID are different identities for the same person. - ATTR_USER_JID | MAYBE_ATTR_USER_JID => ParsedFieldType::UserJid, - ATTR_LID_USER_JID | MAYBE_ATTR_LID_USER_JID => ParsedFieldType::LidUserJid, + ATTR_USER_JID => ParsedFieldType::UserJid, + // The `phone*` spellings are the explicit-PN aliases of the plain user/device + // accessors. + "attrPhoneUserJid" => ParsedFieldType::UserJid, + "attrPhoneDeviceJid" => ParsedFieldType::DeviceJid, + ATTR_LID_USER_JID => ParsedFieldType::LidUserJid, ATTR_DEVICE_JID => ParsedFieldType::DeviceJid, ATTR_LID_DEVICE_JID => ParsedFieldType::LidDeviceJid, ATTR_GROUP_JID => ParsedFieldType::GroupJid, @@ -123,11 +148,24 @@ pub fn method_field_type(m: &str) -> ParsedFieldType { ATTR_CALL_JID => ParsedFieldType::CallJid, ATTR_BROADCAST_JID => ParsedFieldType::BroadcastJid, ATTR_STATUS_JID => ParsedFieldType::StatusJid, - ATTR_JID_WITH_TYPE => ParsedFieldType::JidTyped, + // `attrFromJidChat` / `attrFromJidPhoneChat` both delegate to `attrJidWithType`. + ATTR_JID_WITH_TYPE | "attrJidEnum" | "attrFromJidChat" | "attrFromJidPhoneChat" => { + ParsedFieldType::JidTyped + } // `attrWapJid`/`attrChatJid`/`attrFromJid` accept more than one flavor // (a chat is a user or a group), so they stay a generic `Jid`. ATTR_WAP_JID | ATTR_CHAT_JID | ATTR_FROM_JID => ParsedFieldType::Jid, - CONTENT_BYTES => ParsedFieldType::Bytes, + // Multi-flavor accessors: a chat is a user OR a group, `attrDomainJid`/`attrLidJid` + // accept more than one server, so they stay a generic JID rather than a string. + "attrJid" | "literalJid" | "attrPhoneChatJid" | "attrDomainJid" | "attrLidJid" + | "attrFromPhoneJid" => ParsedFieldType::Jid, + // The enum accessors, whose raw spellings the legacy parsers use directly. + // `contentEnum` reads the content as a string and looks it up. + "attrStringEnum" | "contentStringEnum" | "contentEnum" | "attrEnumOrNullIfUnknown" => { + ParsedFieldType::Enum + } + // Every content accessor that yields raw bytes, whatever length rule it applies. + CONTENT_BYTES | "contentBytesRange" | "contentLiteralBytes" => ParsedFieldType::Bytes, _ => ParsedFieldType::String, } } @@ -196,11 +234,95 @@ mod tests { } } + #[test] + fn maybe_spellings_inherit_their_base_accessor() { + // The rule that replaced enumerating both spellings: a `maybe` variant decodes + // exactly like its base, so a flavour listed once covers both — and a flavour + // never listed defaults visibly for both instead of only for the `maybe` half, + // which is how `maybeAttrPhoneUserJid` came to report a PN user JID as a string. + for base in [ + ATTR_STRING, + ATTR_INT, + ATTR_ENUM, + ATTR_TIME, + ATTR_USER_JID, + ATTR_LID_USER_JID, + ATTR_GROUP_JID, + ATTR_DEVICE_JID, + ATTR_NEWSLETTER_JID, + "attrPhoneUserJid", + ] { + let maybe = format!("maybe{}{}", base[..1].to_uppercase(), &base[1..]); + assert_eq!( + method_field_type(&maybe), + method_field_type(base), + "{maybe} must decode like {base}" + ); + } + // The PN/LID split survives the derivation — the distinction this module calls + // protocol-safety-critical. + assert_eq!( + method_field_type("maybeAttrPhoneUserJid"), + ParsedFieldType::UserJid + ); + assert_eq!( + method_field_type(MAYBE_ATTR_LID_USER_JID), + ParsedFieldType::LidUserJid + ); + assert_ne!( + method_field_type("maybeAttrPhoneUserJid"), + method_field_type(MAYBE_ATTR_LID_USER_JID) + ); + } + + #[test] + fn every_bundle_accessor_is_classified() { + // The accessors WA's parsers actually use, swept from the bundle. Anything here + // that falls through to `String` is either genuinely a string or a flavour we are + // silently dropping — so the list is pinned, and a new one must be judged rather + // than defaulting quietly. + for (m, want) in [ + ("attrFutureTime", ParsedFieldType::Integer), + ("attrIntRange", ParsedFieldType::Integer), + ("contentUint", ParsedFieldType::Integer), + ("contentEnum", ParsedFieldType::Enum), + ("attrStringEnum", ParsedFieldType::Enum), + ("contentStringEnum", ParsedFieldType::Enum), + ("attrEnumOrNullIfUnknown", ParsedFieldType::Enum), + ("contentBytesRange", ParsedFieldType::Bytes), + ("contentLiteralBytes", ParsedFieldType::Bytes), + ("maybeAttrGroupJid", ParsedFieldType::GroupJid), + ("attrPhoneDeviceJid", ParsedFieldType::DeviceJid), + ("attrFromJidChat", ParsedFieldType::JidTyped), + ("attrFromJidPhoneChat", ParsedFieldType::JidTyped), + ("attrJidEnum", ParsedFieldType::JidTyped), + ("attrDomainJid", ParsedFieldType::Jid), + ("attrLidJid", ParsedFieldType::Jid), + ("attrPhoneChatJid", ParsedFieldType::Jid), + ("attrFromPhoneJid", ParsedFieldType::Jid), + ] { + assert_eq!(method_field_type(m), want, "{m}"); + } + // Genuinely strings: a stanza id, and the reference helpers whose type comes from + // the accessor they wrap. + for m in [ + ATTR_STRING, + CONTENT_STRING, + "attrStanzaId", + "attrStringFromReference", + ] { + assert_eq!(method_field_type(m), ParsedFieldType::String, "{m}"); + } + } + #[test] fn optional_and_field_types() { assert!(is_optional_method(MAYBE_ATTR_ENUM)); assert!(!is_optional_method(ATTR_ENUM)); - assert_eq!(method_field_type(MAYBE_ATTR_ENUM), ParsedFieldType::String); + // An enum accessor decodes to an enum, matching how the smax normalizer already + // types the same concept — the two used to disagree across domains. + assert_eq!(method_field_type(MAYBE_ATTR_ENUM), ParsedFieldType::Enum); + assert_eq!(method_field_type(ATTR_ENUM), ParsedFieldType::Enum); assert_eq!(method_field_type(ATTR_INT), ParsedFieldType::Integer); assert_eq!(method_field_type(CONTENT_BYTES), ParsedFieldType::Bytes); assert_eq!( @@ -290,7 +412,7 @@ mod tests { ] { assert!(method_field_type(m).is_jid(), "{m}"); } - assert_eq!(method_field_type(ATTR_ENUM_VALUES), ParsedFieldType::String); + assert_eq!(method_field_type(ATTR_ENUM_VALUES), ParsedFieldType::Enum); // `maybe*` variants stay optional. assert!(is_optional_method(MAYBE_ATTR_TIME)); assert!(is_optional_method(MAYBE_ATTR_USER_JID)); diff --git a/crates/wa-notif/Cargo.toml b/crates/wa-notif/Cargo.toml index 946ef22..abb8bed 100644 --- a/crates/wa-notif/Cargo.toml +++ b/crates/wa-notif/Cargo.toml @@ -12,6 +12,9 @@ description = "Native tooling: oxc AST extraction of WhatsApp Web's incoming sta oxc_allocator = { workspace = true } oxc_ast = { workspace = true } oxc_ast_visit = { workspace = true } +oxc_span = { workspace = true } +oxc_syntax = { workspace = true } +wa-enums = { workspace = true } wa-ir = { workspace = true } wa-oxc = { workspace = true } wa-scan = { workspace = true } diff --git a/crates/wa-notif/src/actions.rs b/crates/wa-notif/src/actions.rs new file mode 100644 index 0000000..b656886 --- /dev/null +++ b/crates/wa-notif/src/actions.rs @@ -0,0 +1,2293 @@ +//! The notification **payload action union** (`w:gp2` and friends). +//! +//! [`crate`] catalogues the notification envelope: which `type`s exist, which handler +//! each forwards to, and the envelope fields (`to`, `from`, `participant`, `t`, +//! `addressing_mode`). What that envelope *carries* is a second, larger union: the +//! handler maps over the notification's children and switches on each child's tag, +//! returning a differently-shaped action per tag. +//! +//! ```js +//! stanza.mapChildren(function (child) { +//! switch (child.tag()) { +//! case TAG.ADD: return { actionType: ACTIONS.ADD, participants: …, reason: … }; +//! case TAG.SUBJECT: return { actionType: ACTIONS.SUBJECT, subject: child.attrString("subject"), … }; +//! case TAG.EPHEMERAL: return { actionType: ACTIONS.EPHEMERAL, duration: child.attrInt("expiration") }; +//! case TAG.NOT_EPHEMERAL: return { actionType: ACTIONS.EPHEMERAL, duration: 0 }; // ← normalised +//! } +//! }) +//! ``` +//! +//! Two things there are unrecoverable from the wire and are what this module exists to +//! pin down. The tag→action mapping is **many-to-one** (`not_ephemeral` normalises into +//! `ephemeral` with `duration: 0`, so a `NOT_EPHEMERAL` branch in a consumer is dead +//! code), and field names are **rebound** (the timer arrives in `expiration` but the +//! action field is `duration`; reading it as `ephemeralDuration` — the *create* +//! payload's spelling — silently yields 0). +//! +//! Both the case labels and the `actionType` values are `Module.CONST.MEMBER` +//! references, so they are resolved against the defining module rather than guessed. + +use std::collections::HashMap; + +use oxc_allocator::Allocator; +use oxc_ast::ast::{Expression, Statement, SwitchStatement}; +use oxc_ast_visit::{Visit, walk}; +use wa_ir::{ + NotifActionChild, NotifActionConstant, NotifActionDef, NotifActionField, NotifConstValue, wap, +}; +use wa_oxc::{arg_expr, as_call, as_identifier, as_int, as_member, as_string_lit, callee_method}; + +/// One exported constant object, as `MEMBER → "wire value"`. +type ConstMap = HashMap; + +/// Resolves `o("Module").CONST_OBJECT.MEMBER` references to their wire string, against +/// the bundle's module slices. Memoized per `(module, object)`. +pub(crate) struct ConstResolver<'a> { + slices: &'a HashMap<&'a str, &'a str>, + cache: std::cell::RefCell>>, + /// `(module, enum)` → its resolved variants. Memoized for the same reason `cache` is: + /// `resolve_named_enum` re-parses the whole module slice, and the resolver is hit once + /// per enum-accessor field — including a second time by the bare-value fallback, which + /// re-walks the same shapes. + enums: std::cell::RefCell>>, + /// Enum-valued action fields whose allowed-value table could not be named, keyed + /// `wireName@table` so two fields losing the same constraint count twice and one + /// field seen twice counts once. + /// + /// The action path has no linker to drain a pending marker, so it reports here. The + /// `w:gp2` `create.reason` field shipped as `"type": "enum"` with no values and no + /// signal anywhere — the exact "lost or absent?" ambiguity the rest of the change + /// exists to remove. + enum_drops: std::cell::RefCell>, +} + +impl<'a> ConstResolver<'a> { + pub(crate) fn new(slices: &'a HashMap<&'a str, &'a str>) -> Self { + Self { + slices, + cache: std::cell::RefCell::new(HashMap::new()), + enums: std::cell::RefCell::new(HashMap::new()), + enum_drops: Default::default(), + } + } + + /// `o("Mod").OBJECT.MEMBER` → the member's string value. + fn member(&self, module: &str, object: &str, member: &str) -> Option { + let key = (module.to_string(), object.to_string()); + if !self.cache.borrow().contains_key(&key) { + let resolved = self + .slices + .get(module) + .and_then(|slice| const_string_map(slice, object)); + self.cache.borrow_mut().insert(key.clone(), resolved); + } + self.cache.borrow()[&key] + .as_ref() + .and_then(|m| m.get(member).cloned()) + } + + /// Resolve the enum argument of an enum accessor — `o("Mod").ENUM_NAME`, a member + /// *reference* rather than a `.MEMBER` lookup — to its full variant set, reusing the + /// same resolver the request and response sides use so all three type an enum + /// attribute identically. + fn enum_ref(&self, e: &Expression) -> Option { + let (obj, name) = as_member(e)?; + let module = as_string_lit(arg_expr(as_call(obj)?.arguments.first()?)?)?; + let key = (module.to_string(), name.to_string()); + if let Some(hit) = self.enums.borrow().get(&key) { + return hit.clone(); + } + let resolved = self.resolve_enum_uncached(module, name); + self.enums.borrow_mut().insert(key, resolved.clone()); + resolved + } + + /// The enum an action field validates against, reporting the loss when there is a + /// table but it is not a nameable `o("Mod").ENUM` reference (a module-local object, + /// a computed set). `wire_name` identifies the occurrence in the report. + fn action_enum_ref( + &self, + method: &str, + arg: Option<&Expression>, + wire_name: &str, + ) -> Option { + if wap::method_field_type(method) != wa_ir::ParsedFieldType::Enum { + return None; + } + let resolved = arg.and_then(|a| self.enum_ref(a)); + if resolved.is_none() { + // Keyed by the table argument's SOURCE SPAN when there is one. `wireName@method` + // was resolver-wide, so two actions each losing `reason` counted once. A span is + // a stronger identity than the action name in both directions: two arms with two + // `attrEnumOrNullIfUnknown("reason", …)` calls are two losses, and two arms + // sharing one helper's call are one constraint referenced twice. + let key = arg.map_or_else( + || format!("{wire_name}@{method}"), + |a| { + let sp = oxc_span::GetSpan::span(a); + format!("{}..{}@{method}", sp.start, sp.end) + }, + ); + self.enum_drops.borrow_mut().insert(key); + } + resolved + } + + /// The allowed-value tables seen on action fields and not recoverable, for + /// `diagnostics.notif.dropsByReason`. + pub(crate) fn take_enum_drops(&self) -> usize { + self.enum_drops.borrow().len() + } + + fn resolve_enum_uncached(&self, module: &str, name: &str) -> Option { + let def = wa_enums::resolve_named_enum(self.slices.get(module)?, module, name)?; + let variants: Vec = def + .variants + .into_iter() + .map(|v| match v.value { + wa_ir::Scalar::Str(s) => Some(wa_ir::AttrEnumVariant { + name: v.name, + value: s, + }), + _ => None, + }) + .collect::>>()?; + (!variants.is_empty()).then(|| wa_ir::AttrEnumRef { + name: name.to_string(), + module: module.to_string(), + variants, + }) + } + + /// Resolve a `o("Mod").OBJECT.MEMBER` expression, or `None` for anything else. + fn resolve(&self, e: &Expression) -> Option { + let (obj, member) = as_member(e)?; + let (owner, object) = as_member(obj)?; + let module = as_string_lit(arg_expr(as_call(owner)?.arguments.first()?)?)?; + self.member(module, object, member) + } +} + +/// Every `NAME: "value"` of a module's exported constant object, whether written as an +/// `Object.freeze({…})`, a `$InternalEnum({…})` or a bare object literal, and whether +/// exported inline (`l.TAGS = {…}`) or through a local (`var e = {…}; l.TAGS = e`). +/// +/// Deliberately its own resolver rather than [`wa_enums::resolve_named_enum`]: that one +/// is intentionally narrow (it gates `Object.freeze` behind an allowlist, because the +/// app has thousands of frozen `CONSTANT_CASE` infra objects that must not leak into the +/// *enum catalog*). Here the object is named by the switch we are already reading, so +/// there is nothing to filter — only one specific export is ever asked for. +fn const_string_map(slice: &str, export: &str) -> Option { + let alloc = Allocator::default(); + let ret = wa_oxc::parse_cjs(&alloc, slice); + if ret.panicked { + return None; + } + let mut collector = ConstCollector { + // Only the module factory's own parameters count as export receivers. Without + // that, `cache.GROUP_ACTIONS = local` written before the real + // `exports.GROUP_ACTIONS = actual` would be taken as the export and — being + // first — kept, resolving case labels through an unrelated table and minting + // wrong wire tags. Empty when the factory shape is not recognised, in which case + // any identifier receiver is accepted, as before: a narrower rule must not turn + // an unfamiliar module into a silently empty one. + receivers: factory_params(&ret.program), + locals: HashMap::new(), + exports: HashMap::new(), + }; + collector.visit_program(&ret.program); + if let Some(Some(direct)) = collector.exports.get(export) { + return match direct { + Export::Inline(map) => Some(map.clone()), + Export::Local(name) => collector.locals.get(name).cloned().flatten(), + }; + } + None +} + +#[derive(PartialEq)] +enum Export { + Inline(ConstMap), + Local(String), +} + +/// The parameter names of the `__d(name, deps, factory)` module factory — the only +/// identifiers a module can legitimately hang an export off. +fn factory_params(program: &oxc_ast::ast::Program) -> Vec { + fn params_of(e: &Expression) -> Option> { + let f = match e { + Expression::ParenthesizedExpression(p) => return params_of(&p.expression), + Expression::FunctionExpression(f) => f, + _ => return None, + }; + Some( + f.params + .items + .iter() + .filter_map(|p| p.pattern.get_identifier_name().map(|n| n.to_string())) + .collect(), + ) + } + for stmt in &program.body { + if let Statement::ExpressionStatement(es) = stmt + && let Some(call) = as_call(&es.expression) + { + for arg in &call.arguments { + if let Some(params) = arg_expr(arg).and_then(params_of) { + return params; + } + } + } + } + Vec::new() +} + +struct ConstCollector { + /// See the note at the construction site. + receivers: Vec, + /// Local name → its all-string object, or `None` when the same minified name is + /// bound to **different** objects in the module. The minifier reuses short + /// identifiers aggressively across nested scopes, so a module-wide "last one wins" + /// map could resolve an export to an unrelated nested table and mint wrong wire tags + /// or `actionType` values. Ambiguity therefore resolves to nothing, which shows up + /// as a missing action rather than a silently wrong one. + locals: HashMap>, + /// `None` marks a property assigned differently through two factory parameters — + /// unresolvable rather than guessed. + exports: HashMap>, +} + +impl<'a> Visit<'a> for ConstCollector { + fn visit_variable_declarator(&mut self, d: &oxc_ast::ast::VariableDeclarator<'a>) { + if let Some(name) = d.id.get_identifier_name() + && let Some(map) = d.init.as_ref().and_then(string_const_object) + { + match self.locals.entry(name.to_string()) { + std::collections::hash_map::Entry::Vacant(e) => { + e.insert(Some(map)); + } + std::collections::hash_map::Entry::Occupied(mut e) => { + // A second, different binding of the same name makes it ambiguous. + if e.get().as_ref() != Some(&map) { + e.insert(None); + } + } + } + } + walk::walk_variable_declarator(self, d); + } + + fn visit_assignment_expression(&mut self, a: &oxc_ast::ast::AssignmentExpression<'a>) { + if let Some(m) = a.left.as_member_expression() + && let Some(prop) = m.static_property_name() + && m.object().get_identifier_reference().is_some_and(|id| { + self.receivers.is_empty() || self.receivers.iter().any(|r| r == id.name.as_str()) + }) + { + // `factory_params` cannot tell the exports binding from the loader or the + // dependency map — WA spells the factory `(t,n,r,o,a,i,l)` and uses `l` in + // some modules and `i` in others. So rather than guess which parameter is + // the real one, a property assigned DIFFERENTLY through two of them is + // refused: the export resolves to nothing, and the failure is a missing + // action rather than a wire tag read out of an unrelated table. + let found = string_const_object(&a.right) + .map(Export::Inline) + .or_else(|| as_identifier(&a.right).map(|id| Export::Local(id.to_string()))); + if let Some(export) = found { + match self.exports.entry(prop.to_string()) { + std::collections::hash_map::Entry::Vacant(e) => { + e.insert(Some(export)); + } + std::collections::hash_map::Entry::Occupied(mut e) => { + if e.get().as_ref() != Some(&export) { + e.insert(None); + } + } + } + } + } + walk::walk_assignment_expression(self, a); + } +} + +/// An all-string-valued object literal, unwrapping the `Object.freeze(…)` / +/// `$InternalEnum(…)` / `ident(…)` single-argument wrappers WA writes them in. +/// `None` if any value isn't a string literal — a mixed object is not a token table. +fn string_const_object(e: &Expression) -> Option { + let obj = match wa_oxc::as_object(e) { + Some(o) => o, + // A single-argument wrapper call: `Object.freeze({…})`, `n("$InternalEnum")({…})`. + None => wa_oxc::as_object(arg_expr(as_call(e)?.arguments.first()?)?)?, + }; + // A spread, a method or a computed key is SKIPPED by `obj_props`, so accepting the + // survivors publishes a partial map: `{ADD: "old", ...base}` resolves `ADD` to `old` + // when the runtime switch uses the spread's value, and a spread-only member vanishes. + // Either way the arm gets a `wireTag`/`actionType` the handler never produces — + // invented, not merely lost. Same rule as the response-side enum tables. + if obj.properties.len() != wa_oxc::obj_props(obj).count() { + return None; + } + let mut map = ConstMap::new(); + for (key, value) in wa_oxc::obj_props(obj) { + map.insert(key.to_string(), as_string_lit(value)?.to_string()); + } + (!map.is_empty()).then_some(map) +} + +/// Extract a handler module's payload action union, if it has one. +/// +/// Locates the `switch` whose cases are `Module.CONST.MEMBER` references resolving to +/// wire strings — the child-tag dispatch — and reads one [`NotifActionDef`] per arm. +/// `None` when the module has no such switch (most handlers forward straight to a +/// parser and carry no action union). +pub(crate) fn extract_actions( + handler_slice: &str, + consts: &ConstResolver, +) -> Option> { + let alloc = Allocator::default(); + let ret = wa_oxc::parse_cjs(&alloc, handler_slice); + if ret.panicked { + return None; + } + // Arms routinely delegate the bulk of their shape to a module-local helper + // (`participants: y(chat, child, tag)` is where every participant list lives), so + // the helpers are indexed up front and inlined on demand. + let mut locals = LocalFns::default(); + locals.visit_program(&ret.program); + // A minified helper name reused by a nested function would otherwise resolve to + // whichever declaration was visited last, letting an arm inline an unrelated + // function and emit wrong fields. Ambiguity resolves to nothing instead — the same + // rule the constant tables use — so the failure is a missing action, not a wrong one. + let mut by_name: HashMap> = HashMap::new(); + for (name, (a, b)) in locals.spans { + let src = handler_slice[a..b].to_string(); + match by_name.entry(name) { + std::collections::hash_map::Entry::Vacant(e) => { + e.insert(Some(src)); + } + std::collections::hash_map::Entry::Occupied(mut e) => { + if e.get().as_deref() != Some(src.as_str()) { + e.insert(None); + } + } + } + } + let ctx = ArmCtx { + consts, + source: handler_slice, + locals: by_name + .into_iter() + .filter_map(|(n, src)| src.map(|s| (n, s))) + .collect(), + }; + let mut finder = SwitchFinder { + ctx: &ctx, + best: None, + tag_locals: Default::default(), + }; + finder.visit_program(&ret.program); + finder.best.filter(|v| !v.is_empty()) +} + +/// What an arm reader needs: the constant tables its labels resolve through, and the +/// module's local helper functions, as re-parsable source (keyed by name). +struct ArmCtx<'c, 'a> { + consts: &'c ConstResolver<'a>, + locals: HashMap, + /// The handler module's source, so an inlined helper can be given the TEXT of the + /// arguments it was called with. The helper is re-parsed in its own allocator, so a + /// call-site AST reference cannot cross into it — its source can. + source: &'c str, +} + +/// Collects `function name(…){…}` / `var name = function(…){…}` spans in a module. +#[derive(Default)] +struct LocalFns { + spans: Vec<(String, (usize, usize))>, +} + +impl<'a> Visit<'a> for LocalFns { + fn visit_function( + &mut self, + f: &oxc_ast::ast::Function<'a>, + flags: oxc_syntax::scope::ScopeFlags, + ) { + if let Some(id) = f.id.as_ref() { + let sp = oxc_span::GetSpan::span(f); + self.spans + .push((id.name.to_string(), (sp.start as usize, sp.end as usize))); + } + walk::walk_function(self, f, flags); + } + + fn visit_variable_declarator(&mut self, d: &oxc_ast::ast::VariableDeclarator<'a>) { + if let (Some(name), Some(init)) = (d.id.get_identifier_name(), d.init.as_ref()) + && matches!( + init, + Expression::FunctionExpression(_) | Expression::ArrowFunctionExpression(_) + ) + { + let sp = oxc_span::GetSpan::span(init); + self.spans + .push((name.to_string(), (sp.start as usize, sp.end as usize))); + } + walk::walk_variable_declarator(self, d); + } +} + +struct SwitchFinder<'c, 'a> { + ctx: &'c ArmCtx<'c, 'a>, + /// The richest action union seen so far (a module can hold more than one + /// const-keyed switch; the payload union is the one with the most arms). + best: Option>, + /// Locals bound to a child's TAG in the function currently being walked + /// (`var a = t.tag()`), so a switch can be identified by what it dispatches ON + /// rather than by how many arms it happens to have. + tag_locals: std::collections::HashSet, +} + +/// Whether `e` reads a node's tag — `t.tag()` or `t.tag`. +fn is_tag_read(e: &Expression) -> bool { + if let Some(call) = as_call(e) { + return callee_method(call) == Some("tag") && call.arguments.is_empty(); + } + as_member(e).is_some_and(|(_, name)| name == "tag") +} + +impl<'a> Visit<'a> for SwitchFinder<'_, 'a> { + /// Record this function's `var x = child.tag()` bindings before walking its body, + /// so a switch inside it can be checked against them. + fn visit_function_body(&mut self, body: &oxc_ast::ast::FunctionBody<'a>) { + let outer = std::mem::take(&mut self.tag_locals); + for st in &body.statements { + if let Statement::VariableDeclaration(d) = st { + for decl in &d.declarations { + if let (Some(n), Some(init)) = + (decl.id.get_identifier_name(), decl.init.as_ref()) + && is_tag_read(init) + { + self.tag_locals.insert(n.as_str().to_string()); + } + } + } + } + walk::walk_function_body(self, body); + self.tag_locals = outer; + } + + fn visit_switch_statement(&mut self, switch: &SwitchStatement<'a>) { + // Identified by what it dispatches ON, not by size. The payload union switches on + // a mapped child's TAG (`var a = t.tag(); switch (a)`); an unrelated const-keyed + // switch in the same module — with more returning arms — would otherwise win the + // "most arms" tie-break and publish non-wire constants as `wireTag`s. + let on_tag = is_tag_read(&switch.discriminant) + || as_identifier(&switch.discriminant).is_some_and(|n| self.tag_locals.contains(n)); + if !on_tag { + walk::walk_switch_statement(self, switch); + return; + } + let actions = extract_switch(switch, self.ctx); + // A const-keyed switch whose arms only cause side effects is not a payload action + // union — it is an ordinary child dispatch, already described by the + // notification's `content` and sub-discriminants. `account_sync` has one, and + // cataloguing it minted 11 phantom actions with no action type, field, constant + // or child, inflating the count with entries a consumer can do nothing with. An + // individual empty arm is still kept (knowing a tag is dispatched beats omitting + // it); a switch where EVERY arm is empty is rejected whole. + if actions.iter().any(is_meaningful) + && actions.len() > self.best.as_ref().map_or(0, Vec::len) + { + self.best = Some(actions); + } + walk::walk_switch_statement(self, switch); + } +} + +/// Whether an arm says anything beyond "this tag is dispatched". +fn is_meaningful(a: &NotifActionDef) -> bool { + a.action_type.is_some() + || !a.fields.is_empty() + || !a.constant_fields.is_empty() + || !a.children.is_empty() +} + +/// Read every arm of a const-keyed child-tag switch into [`NotifActionDef`]s. +fn extract_switch(switch: &SwitchStatement, ctx: &ArmCtx) -> Vec { + let mut out = Vec::new(); + for (i, case) in switch.cases.iter().enumerate() { + let Some(wire_tag) = case.test.as_ref().and_then(|t| ctx.consts.resolve(t)) else { + continue; + }; + // `case TAG_A: case TAG_B: return {…}` — a fall-through label runs the next case + // that actually produces something. Stopping at the first NON-EMPTY consequent is + // not enough: a label may do setup or log first (`case TAG_A: log();`) and still + // fall through, and treating that as its own arm loses the action type and every + // field of a legally dispatched tag. Search forward for the first case that + // yields a result shape instead. + // …but the chain ENDS at a terminating statement. `case A: log(); break; case B: + // return {…}` does not fall through, and scanning past the `break` would publish + // B's action type and fields under A's wire tag — a shape that tag never produces. + let run: Vec<&Statement> = + fall_through_body(&switch.cases[i..]).unwrap_or_else(|| as_refs(&case.consequent)); + let shapes = arm_result_shapes_of(&run); + if shapes.is_empty() { + // A recognised tag whose arm returns no shape (a bare flag set, an early + // break). Still catalogued: knowing the tag is dispatched at all beats + // omitting it. + out.push(empty_action(wire_tag)); + continue; + } + // An arm can branch into more than one shape. Which of the two it is matters: + // `description` branches into two DIFFERENT actions (`desc_remove` when the + // child has a ``, else `desc_add`), while `ephemeral` branches into the + // SAME action behind a feature flag, differing only in extra optional fields. + // So branches are grouped by `actionType`: different ones stay separate arms of + // the union, identical ones merge into one (a field only some branches read is + // optional in the merge). + let mut grouped: Vec = Vec::new(); + for (shape, scope) in shapes { + for action in expand_shape(&wire_tag, shape, &scope, ctx, 0) { + match grouped + .iter_mut() + .find(|g| g.def.action_type == action.action_type) + { + Some(fold) => fold.absorb(action), + None => grouped.push(BranchFold::new(action)), + } + } + } + out.extend(grouped.into_iter().map(BranchFold::finish)); + } + out +} + +/// The body a case actually runs, following the fall-through chain. +/// +/// Starting at the case itself, walk forward until one yields a result shape — a label +/// may do setup or log before falling through, so "the first non-empty consequent" is not +/// the answer. The chain **ends** at a terminating statement: `case A: log(); break;` does +/// not fall through, and continuing past it would publish the next case's action under +/// A's wire tag, a shape that tag never produces. +fn fall_through_body<'b, 'a>( + cases: &'b [oxc_ast::ast::SwitchCase<'a>], +) -> Option>> { + // Everything the chain executes, in order — not just the case that returns. A label + // may bind before falling through (`case A: var id = child.attrString("id"); case B: + // return {id}`), and handing back only B's body drops `id` from A's scope. + let mut run: Vec<&Statement> = Vec::new(); + let mut produced = false; + for case in cases { + run.extend(case.consequent.iter()); + produced |= !arm_result_shapes(&case.consequent).is_empty(); + // Only a case that terminates on EVERY path stops the chain. A shape found here + // is not enough: `case A: if (cond) return X; case B: return Y;` legally produces + // either, and stopping at A published only X. Keep walking and let the collected + // shapes accumulate — `collect_returns` reads them all out of `run`. + if terminates(&case.consequent) { + return produced.then_some(run); + } + } + produced.then_some(run) +} + +/// Whether a case body ends its own control flow on **every** path rather than falling +/// through. +/// +/// "Every path" is what makes it safe for [`fall_through_body`] to stop here, and it is +/// load-bearing now that a collected shape no longer stops the walk: `if (cond) return X;` +/// leaves a path open and must fall through, while `switch (t) { case "a": return X; +/// default: return Y }` closes them all and must not. +fn terminates(stmts: &[Statement]) -> bool { + list_exits(stmts, false) +} + +/// Whether the list leaves the enclosing case on every path. +/// +/// Order matters, and `any` got it wrong: in `case X: if (cond) break; return A;` inside a +/// nested switch, the `break` leaves only the INNER switch and control resumes in the +/// outer case, yet the later `return` made the whole list look terminating. A statement +/// that can escape upward poisons the conclusion before any later statement is consulted. +fn list_exits(stmts: &[Statement], nested: bool) -> bool { + list_exits_refs(&stmts.iter().collect::>(), nested) +} + +/// [`list_exits`] over borrowed statements, so a fall-through suffix can be assembled +/// across cases without cloning the AST. +fn list_exits_refs(stmts: &[&Statement], nested: bool) -> bool { + for s in stmts.iter().copied() { + if can_escape(s, nested) { + return false; + } + if stmt_exits(s, nested) { + return true; + } + } + false +} + +/// Whether some path through `s` reaches a `break` that leaves the construct we are +/// analysing rather than ending the case. Only meaningful inside a nested breakable +/// construct — at case level a `break` *is* the exit. +fn can_escape(s: &Statement, nested: bool) -> bool { + if !nested { + return false; + } + match s { + Statement::BreakStatement(_) => true, + Statement::BlockStatement(b) => b.body.iter().any(|s| can_escape(s, nested)), + Statement::IfStatement(i) => { + can_escape(&i.consequent, nested) + || i.alternate.as_ref().is_some_and(|a| can_escape(a, nested)) + } + // A deeper switch or loop consumes the `break` itself, so it cannot reach us. + _ => false, + } +} + +/// Whether `s` exits the enclosing switch case on every path. +/// +/// `nested` says whether a bare `break` would leave an inner breakable construct instead +/// of the case — inside a nested `switch`, `break` returns control to the case and is not +/// an exit at all. +fn stmt_exits(s: &Statement, nested: bool) -> bool { + match s { + Statement::ReturnStatement(_) | Statement::ThrowStatement(_) => true, + Statement::BreakStatement(_) | Statement::ContinueStatement(_) => !nested, + Statement::BlockStatement(b) => list_exits(&b.body, nested), + // Both arms, or the statement after the `if` still runs. + Statement::IfStatement(i) => i + .alternate + .as_ref() + .is_some_and(|alt| stmt_exits(&i.consequent, nested) && stmt_exits(alt, nested)), + // Exhaustive only with a `default`, and only if every case leaves the switch — + // which each case may do through its own fall-through suffix, not just its own + // body. `case X: setup(); default: return A` exits on both paths: `X` runs + // `setup()` and falls into the default's `return`. Requiring the body alone to + // exit (accepting only an EMPTY fall-through label) called that switch + // non-terminating, and the enclosing case then borrowed the next outer case's + // action for a wire tag that never produces it. + // A `finally` that exits settles it on its own; otherwise the `try` body must + // exit and, if there is a handler, so must it. `try { return X } finally + // { return Y }` always returns, and treating it as fall-through let the arm + // borrow the next case's action. + Statement::TryStatement(t) => { + let finalizer_exits = t + .finalizer + .as_ref() + .is_some_and(|f| list_exits(&f.body, nested)); + finalizer_exits + || (list_exits(&t.block.body, nested) + && t.handler + .as_ref() + .is_none_or(|h| list_exits(&h.body.body, nested))) + } + // A `do…while` body runs at least once, so if it exits on every path the loop + // does. `do { return A } while (c); return B` was collecting A and then walking + // on to publish the unreachable B. + // The body's own `break`/`continue` are consumed by THIS loop, so they cannot + // prove it exits its caller: `do { break; } while (c); return B` reaches B. + Statement::DoWhileStatement(d) => !can_escape(&d.body, true) && stmt_exits(&d.body, nested), + Statement::SwitchStatement(sw) => { + sw.cases.iter().any(|c| c.test.is_none()) + && (0..sw.cases.len()).all(|i| { + let suffix: Vec<&Statement> = sw.cases[i..] + .iter() + .flat_map(|c| c.consequent.iter()) + .collect(); + list_exits_refs(&suffix, true) + }) + } + _ => false, + } +} + +fn empty_action(wire_tag: String) -> NotifActionDef { + NotifActionDef { + wire_tag, + action_type: None, + fields: Vec::new(), + constant_fields: Vec::new(), + children: Vec::new(), + } +} + +/// The union of one wire tag's branches, accumulated. +/// +/// **One** implementation of the alternative rule, because writing it per level is what +/// kept going wrong: the rule lived in three places (scalars, children, child fields) and +/// each review round fixed the copy that had been pointed at while the others stayed +/// stale. Every tombstone below lives for the whole fold rather than one call of it — +/// that was the other half of the same bug, since a conflict removed by branch B is +/// re-added by branch C if the state resets in between. +/// +/// The rule itself: a field either branch reads is present; it is required only when +/// EVERY branch reads it unconditionally; and a key two branches bind to *different* wire +/// reads is refused, because reporting one of them describes the other branch's payload +/// wrongly. Distinct from composition *within* one shape (`babelHelpers.extends`, a +/// duplicate object key), where the last write simply wins — see [`merge_into`]. +struct BranchFold { + def: NotifActionDef, + /// Scalar keys two branches disagreed on. + dead: Conflicts, + /// Child names bound to two different wire tags. + dead_children: Conflicts, + /// Per child name, the field keys its branches disagreed on. + dead_child_fields: HashMap, +} + +impl BranchFold { + fn new(def: NotifActionDef) -> Self { + Self { + def, + dead: Conflicts::new(), + dead_children: Conflicts::new(), + dead_child_fields: HashMap::new(), + } + } + + /// Fold one more branch of the same action into the union. + fn absorb(&mut self, from: NotifActionDef) { + if self.def.action_type.is_none() { + self.def.action_type = from.action_type; + } + merge_fields(&mut self.def.fields, from.fields, false, &mut self.dead); + for c in from.children { + match self.def.children.iter_mut().find(|x| x.name == c.name) { + // Same output name and the same element: their field sets are + // alternatives and merge under the rule above. + Some(existing) if existing.wire_tag == c.wire_tag => { + let dead = self.dead_child_fields.entry(c.name.clone()).or_default(); + merge_fields(&mut existing.fields, c.fields, false, dead); + } + // Same name, different element. Leaving the first would tell a consumer + // every legal shape uses it. + Some(existing) => { + self.dead_children.insert(existing.name.clone()); + } + None => self.def.children.push(c), + } + } + // A constant only some branches stamp is not a property of the action. + self.def + .constant_fields + .retain(|c| from.constant_fields.contains(c)); + } + + /// Apply every tombstone. Run once, after the last branch. + fn finish(mut self) -> NotifActionDef { + apply_conflicts(&mut self.def.fields, &self.dead); + self.def + .children + .retain(|c| !self.dead_children.contains(&c.name)); + for c in &mut self.def.children { + if let Some(dead) = self.dead_child_fields.get(&c.name) { + apply_conflicts(&mut c.fields, dead); + } + } + self.def + } +} + +/// Every distinct result shape an arm can return: one per branch of a `cond ? A : B` +/// (nested ternaries included), each with its `babelHelpers.extends(…)` merged away. +fn arm_result_shapes<'b, 'a>(consequent: &'b [Statement<'a>]) -> Vec> { + arm_result_shapes_of(&as_refs(consequent)) +} + +/// As [`arm_result_shapes`], over a statement list assembled from several sources — the +/// fall-through chain runs the statements of every case it passes through, not only the +/// one that returns. +fn arm_result_shapes_of<'b, 'a>(consequent: &[&'b Statement<'a>]) -> Vec> { + arm_result_shapes_in(consequent, &Scope::new()) +} + +fn as_refs<'b, 'a>(stmts: &'b [Statement<'a>]) -> Vec<&'b Statement<'a>> { + stmts.iter().collect() +} + +/// As [`arm_result_shapes`], with an enclosing scope the branches layer over. +fn arm_result_shapes_in<'b, 'a>( + consequent: &[&'b Statement<'a>], + outer: &Scope<'b, 'a>, +) -> Vec> { + let unwrapped; + let stmts: &[&Statement] = match consequent { + [Statement::BlockStatement(b)] => { + unwrapped = as_refs(&b.body); + &unwrapped + } + other => other, + }; + let mut out = Vec::new(); + collect_returns(stmts, outer, &mut out); + out +} + +/// Every `return` reachable in `stmts`, descending through control flow (`if`/`else`, +/// blocks, `try`, a nested `switch`) but never into a nested function — an arm or helper that +/// writes `if (cond) return {actionType: A, …}; return {actionType: B, …}` exposes both +/// shapes, where a direct-children-only scan would silently keep just the last. +/// The result shapes of a function expression, handling the implicit return of an +/// expression-bodied arrow (`p => userJidToUserWid(p.attrUserJid("jid"))`), whose body +/// oxc stores as a lone `ExpressionStatement` rather than a `return`. +fn fn_result_shapes<'b, 'a>(e: &'b Expression<'a>, base: &Scope<'b, 'a>) -> Vec> { + if let Expression::ArrowFunctionExpression(arrow) = e + && let Some(expr) = arrow.get_expression() + { + let mut branches = Vec::new(); + collect_branches(expr, &mut branches); + return branches.into_iter().map(|x| (x, base.clone())).collect(); + } + function_body_of(e) + .map(|stmts| arm_result_shapes_in(&as_refs(stmts), base)) + .unwrap_or_default() +} + +fn collect_returns<'b, 'a>( + stmts: &[&'b Statement<'a>], + outer: &Scope<'b, 'a>, + out: &mut Vec>, +) { + // Bindings accumulate in STATEMENT ORDER and each return snapshots what is in scope + // where it sits. A pre-pass over the whole list would install a later initializer + // before an earlier return: `var x = attr("a"); if (c) return {a:x}; var x = + // attr("b")` would report the first branch as reading `b`, an assignment that has + // not run. Hoisting moves the declaration, not the assignment. + // + // Scopes are also per branch, because mutually exclusive branches routinely rebind + // the same minified name to different accessors, and one flattened scope would make + // one branch's return read the other branch's attribute — a wrong `wireName` rather + // than a missing field. + let mut scope = outer.clone(); + collect_returns_into(stmts, &mut scope, out); +} + +/// [`collect_returns`] over a scope the caller owns, so a construct that always runs — +/// a bare block — can hand its writes back instead of having them discarded with a clone. +fn collect_returns_into<'b, 'a>( + stmts: &[&'b Statement<'a>], + scope: &mut Scope<'b, 'a>, + out: &mut Vec>, +) { + for s in stmts.iter().copied() { + match s { + Statement::VariableDeclaration(decl) => { + for d in &decl.declarations { + if let (Some(name), Some(init)) = (d.id.get_identifier_name(), d.init.as_ref()) + { + scope.insert(name.as_str(), init); + } + } + } + // `x = child.attrString("lid")` — a reassignment, not a declaration. The + // minifier hoists a `var` to the top and assigns later, so handling only + // declarations left the *initializer* installed at every return below the + // assignment: the runtime read `lid` while the IR published `jid`. + // + // An assignment whose right-hand side is not a wire read REMOVES the binding + // rather than leaving the old one: the name no longer holds what it held, and + // reporting a value that has been overwritten is worse than reporting none. + // The minifier also writes runs of assignments as one comma sequence + // (`a = t.attrString("jid"), b = t.attrInt("n")`), which arrives as a + // `SequenceExpression`; matching only a bare assignment skipped those + // entirely and left the stale initializer installed. + Statement::ExpressionStatement(e) => { + // A write buried in a short-circuit or ternary runs on SOME paths only: + // `cond && (x = attrString("lid"))` leaves `x` holding either value, so + // the name no longer has one known source and is tombstoned. Ignoring it + // left the pre-expression binding installed and published it as fact. + for name in conditional_writes(&e.expression) { + scope.remove(name); + } + let mut ops = Vec::new(); + flatten_sequence(&e.expression, &mut ops); + for a in ops { + if let Some(name) = a.left.get_identifier_name() { + // The binding now holds the new right-hand side, whatever it is. + // Requiring it to resolve to a wire accessor dropped the minifier's + // `var x; x = {actionType: A, id: attr("jid")}; return x` — a fully + // static shape — and published an empty action. Pointing the name at + // what it now holds satisfies the "never report an overwritten + // value" rule better than forgetting it: if the new value is not + // interpretable, the field simply does not resolve. + scope.insert(name, &a.right); + } + } + } + Statement::ReturnStatement(r) => { + if let Some(arg) = r.argument.as_ref() { + let mut branches = Vec::new(); + collect_branches(arg, &mut branches); + out.extend(branches.into_iter().map(|e| (e, scope.clone()))); + } + } + // A bare block ALWAYS runs and `var` is function-scoped, so its writes + // survive it: `{ x = child.attrString("lid"); } return {id: x}` reads `lid`. + // Analyzing it against a clone discarded that and published the pre-block + // source. (A branch's block is different — it reaches here through the `if` + // arm below, which clones deliberately.) + Statement::BlockStatement(b) => { + // `var` writes escape a bare block (function scope); `let`/`const` do not. + // Propagating everything let an inner `let x` shadow the outer `x` for the + // rest of the function — the runtime reads the OUTER value after the block. + let shadowed: Vec<(&str, Option<&'b Expression<'a>>)> = block_scoped_names(&b.body) + .into_iter() + .map(|n| (n, scope.get(n).copied())) + .collect(); + collect_returns_into(&as_refs(&b.body), scope, out); + for (name, prior) in shadowed { + match prior { + Some(e) => scope.insert(name, e), + None => scope.remove(name), + }; + } + } + Statement::IfStatement(i) => { + collect_returns(&[&i.consequent], scope, out); + if let Some(alt) = &i.alternate { + collect_returns(&[alt], scope, out); + } + // Where the branches rejoin, a name either branch reassigned no longer has + // one known value: `var x = attrString("jid"); if (c) x = attrString("lid"); + // return {id: x}` reads `lid` on one legal path, and keeping the pre-branch + // binding published `jid` as if it were certain. Tombstoned rather than + // guessed, the same way a key bound to two different reads is refused. + tombstone_branch_writes(s, scope); + } + Statement::TryStatement(t) => { + // The `try` body and its `catch` are alternative paths — WA wraps a + // parse in `try { … } catch (e) { … }` and the handler's return is as + // legal as the body's — and both see the pre-`try` scope, since nothing + // the body wrote is guaranteed to have run when the handler is entered. + let mut paths = Vec::new(); + collect_returns(&as_refs(&t.block.body), scope, &mut paths); + if let Some(h) = &t.handler { + // The catch PARAMETER is the caught exception, not whatever the outer + // scope bound to that name. `var e = attrString("jid"); try {…} + // catch (e) { return {id: e} }` published `id` as a read of `jid`; + // masking it makes the handler's `e` resolve to nothing, which is the + // truth. + let mut catch_scope = scope.clone(); + if let Some(param) = h.param.as_ref() + && let Some(name) = param.pattern.get_identifier_name() + { + catch_scope.remove(name.as_str()); + } + collect_returns(&as_refs(&h.body.body), &catch_scope, &mut paths); + } + // What the finalizer does to the earlier shapes is a control-flow + // question, not a "did it yield anything" one. Emptiness gets both ends + // wrong: `finally { if (c) return B }` keeps A legal when `c` is false, + // and `finally { throw e }` yields nothing at all yet leaves the vector + // empty. Only a finalizer that leaves on EVERY path replaces them. + let mut finalizer = Vec::new(); + if let Some(f) = &t.finalizer { + // The finalizer runs AFTER the try body, so the entry scope is wrong: + // `var x = a("jid"); try { x = a("lid") } finally { return {id: x} }` + // returns `lid`. The body may also have thrown part-way, so neither + // binding is certain — every name the try or catch writes is + // tombstoned for the finalizer, the same conservative merge used + // where branches rejoin. + let mut fin_scope = scope.clone(); + tombstone_branch_writes(s, &mut fin_scope); + collect_returns(&as_refs(&f.body), &fin_scope, &mut finalizer); + } + let finalizer_settles = t + .finalizer + .as_ref() + .is_some_and(|f| list_exits(&f.body, false)); + if !finalizer_settles { + out.extend(paths); + } + out.extend(finalizer); + // A `try` body may have run in part; nothing IT wrote is certain after it. + // The FINALIZER is different: it runs on every path, so its writes are + // definite and tombstoning them lost fields the return always reads. + // Uncertain try/catch writes are dropped first, then the finalizer's are + // replayed over the result. + tombstone_branch_writes(s, scope); + if let Some(f) = &t.finalizer { + replay_writes(&f.body, scope); + } + } + // A nested `switch` inside an arm (or a helper body) is how THAT arm picks + // its shape — `case LINK: switch (linkType) { case "parent": return {…}; + // default: return {…} }` describes two legal actions for `link`, and skipping + // it left the arm empty. Nested *functions* are still not descended into, + // which is what keeps the top-level child-tag dispatch out of a helper's + // returns. + Statement::SwitchStatement(sw) => { + // Each case is analyzed with its own FALL-THROUGH SUFFIX, the same rule + // the outer action switch follows: `case "a": x = attrString("jid"); + // case "b": return {id: x}` runs the assignment on the `a` path, and + // analyzing the consequents independently lost `id` there. + for i in 0..sw.cases.len() { + let mut run: Vec<&Statement> = Vec::new(); + for c in &sw.cases[i..] { + run.extend(c.consequent.iter()); + if list_exits(&c.consequent, true) { + break; + } + } + collect_returns(&run, scope, out); + } + tombstone_branch_writes(s, scope); + } + // A loop body is a conditional path like any other: `while (c) { return A } + // return B` legally produces both, and falling into the catch-all collected + // only B. Its writes are tombstoned on exit for the same reason a branch's + // are — the body may have run any number of times, including zero. + // A `do…while` body runs AT LEAST once, so its writes are definite — the + // ordinary loop merge tombstoned them and lost every field they bound. + Statement::DoWhileStatement(d) => { + // The body runs at least once, so its writes are definite — UNLESS a path + // leaves it early: `do { if (c) break; x = a("lid"); } while (…)` reaches + // the return without assigning `x`, and propagating unconditionally + // recorded `lid` as its one certain source. + if can_escape(&d.body, true) { + collect_returns(&[&d.body], scope, out); + tombstone_branch_writes(s, scope); + } else { + collect_returns_into(&[&d.body], scope, out); + } + } + Statement::ForStatement(_) + | Statement::ForInStatement(_) + | Statement::ForOfStatement(_) + | Statement::WhileStatement(_) => { + // A `for` INITIALIZER runs before every path that enters the body, so it + // is a definite write for the body's scope — `for (x = a("lid"); …;) + // return {id: x}` always reads `lid`, and analyzing the body against the + // pre-loop scope published the stale source. + let mut entry = scope.clone(); + if let Statement::ForStatement(f) = s { + match &f.init { + Some(oxc_ast::ast::ForStatementInit::VariableDeclaration(d)) => { + for decl in &d.declarations { + if let (Some(n), Some(init)) = + (decl.id.get_identifier_name(), decl.init.as_ref()) + { + entry.insert(n.as_str(), init); + } + } + } + Some(init) => { + if let Some(e) = init.as_expression() { + let mut ops = Vec::new(); + flatten_sequence(e, &mut ops); + for a in ops { + if let Some(n) = a.left.get_identifier_name() { + entry.insert(n, &a.right); + } + } + } + } + None => {} + } + } + if let Some(body) = loop_body(s) { + collect_returns(&[body], &entry, out); + } + tombstone_branch_writes(s, scope); + } + _ => {} + } + // Nothing after a statement that leaves on every path runs. This covers the bare + // `return` and, equally, `if (c) return A; else return B;` — whose trailing + // `return C` is unreachable yet was emitted as a third legal action. + if stmt_exits(s, false) { + return; + } + } +} + +/// The names a statement list declares with `let`/`const` — bindings that die with their +/// block, unlike `var`. +fn block_scoped_names<'b, 'a>(stmts: &'b [Statement<'a>]) -> Vec<&'b str> { + use oxc_ast::ast::VariableDeclarationKind as K; + let mut out = Vec::new(); + for s in stmts { + if let Statement::VariableDeclaration(d) = s + && matches!(d.kind, K::Let | K::Const) + { + out.extend( + d.declarations + .iter() + .filter_map(|x| x.id.get_identifier_name()) + .map(|n| n.as_str()), + ); + } + } + out +} + +/// The body statement of any loop form, so one arm can handle them all. +fn loop_body<'b, 'a>(s: &'b Statement<'a>) -> Option<&'b Statement<'a>> { + match s { + Statement::ForStatement(f) => Some(&f.body), + Statement::ForInStatement(f) => Some(&f.body), + Statement::ForOfStatement(f) => Some(&f.body), + Statement::WhileStatement(w) => Some(&w.body), + Statement::DoWhileStatement(d) => Some(&d.body), + _ => None, + } +} + +/// The assignment operands of an expression, flattening the minifier's comma sequences. +fn flatten_sequence<'b, 'a>( + e: &'b Expression<'a>, + out: &mut Vec<&'b oxc_ast::ast::AssignmentExpression<'a>>, +) { + match e { + Expression::AssignmentExpression(a) => out.push(a), + Expression::SequenceExpression(seq) => { + for sub in &seq.expressions { + flatten_sequence(sub, out); + } + } + Expression::ParenthesizedExpression(p) => flatten_sequence(&p.expression, out), + _ => {} + } +} + +/// Names assigned inside a CONDITIONAL part of an expression — an operand of `&&`/`||` +/// or either arm of a ternary. Definite top-level writes are excluded; [`flatten_sequence`] +/// handles those. +fn conditional_writes<'b>(e: &'b Expression) -> Vec<&'b str> { + fn walk<'b>(e: &'b Expression, guarded: bool, out: &mut Vec<&'b str>) { + match e { + Expression::AssignmentExpression(a) => { + if guarded && let Some(n) = a.left.get_identifier_name() { + out.push(n); + } + walk(&a.right, guarded, out); + } + Expression::LogicalExpression(l) => { + walk(&l.left, guarded, out); + walk(&l.right, true, out); + } + Expression::ConditionalExpression(c) => { + walk(&c.test, guarded, out); + walk(&c.consequent, true, out); + walk(&c.alternate, true, out); + } + Expression::SequenceExpression(seq) => { + for sub in &seq.expressions { + walk(sub, guarded, out); + } + } + Expression::ParenthesizedExpression(p) => walk(&p.expression, guarded, out), + _ => {} + } + } + let mut out = Vec::new(); + walk(e, false, &mut out); + out +} + +/// Re-apply the writes a statement list performs, for a construct that runs on EVERY +/// path (a `finally`). Only top-level declarations and assignments; anything conditional +/// inside stays out, which is what keeps this from re-asserting an uncertain value. +fn replay_writes<'b, 'a>(stmts: &'b [Statement<'a>], scope: &mut Scope<'b, 'a>) { + for st in stmts { + match st { + Statement::VariableDeclaration(d) => { + for decl in &d.declarations { + if let (Some(n), Some(init)) = + (decl.id.get_identifier_name(), decl.init.as_ref()) + { + scope.insert(n.as_str(), init); + } + } + } + Statement::ExpressionStatement(e) => { + let mut ops = Vec::new(); + flatten_sequence(&e.expression, &mut ops); + for a in ops { + if let Some(n) = a.left.get_identifier_name() { + scope.insert(n, &a.right); + } + } + } + _ => {} + } + } +} + +/// Drop every binding a conditional construct may have reassigned, so statements after +/// the rejoin do not read a value that only one path wrote. +fn tombstone_branch_writes(s: &Statement, scope: &mut Scope) { + let mut names = Vec::new(); + assigned_names(s, &mut names); + for n in names { + scope.remove(n); + } +} + +/// Every identifier assigned anywhere inside `s`, not descending into nested functions +/// (whose assignments belong to their own scope, not this one). +fn assigned_names<'a>(s: &'a Statement, out: &mut Vec<&'a str>) { + fn expr<'a>(e: &'a Expression, out: &mut Vec<&'a str>) { + match e { + Expression::AssignmentExpression(a) => { + if let Some(n) = a.left.get_identifier_name() { + out.push(n); + } + expr(&a.right, out); + } + Expression::SequenceExpression(seq) => { + seq.expressions.iter().for_each(|e| expr(e, out)) + } + Expression::ParenthesizedExpression(p) => expr(&p.expression, out), + Expression::ConditionalExpression(c) => { + expr(&c.test, out); + expr(&c.consequent, out); + expr(&c.alternate, out); + } + Expression::LogicalExpression(l) => { + expr(&l.left, out); + expr(&l.right, out); + } + _ => {} + } + } + match s { + Statement::ExpressionStatement(e) => expr(&e.expression, out), + Statement::VariableDeclaration(d) => { + for decl in &d.declarations { + if let (Some(n), Some(_)) = (decl.id.get_identifier_name(), decl.init.as_ref()) { + out.push(n.as_str()); + } + } + } + Statement::BlockStatement(b) => b.body.iter().for_each(|s| assigned_names(s, out)), + Statement::IfStatement(i) => { + expr(&i.test, out); + assigned_names(&i.consequent, out); + if let Some(a) = &i.alternate { + assigned_names(a, out); + } + } + s if loop_body(s).is_some() => { + if let Some(b) = loop_body(s) { + assigned_names(b, out); + } + } + Statement::TryStatement(t) => { + t.block.body.iter().for_each(|s| assigned_names(s, out)); + if let Some(h) = &t.handler { + h.body.body.iter().for_each(|s| assigned_names(s, out)); + } + if let Some(f) = &t.finalizer { + f.body.iter().for_each(|s| assigned_names(s, out)); + } + } + Statement::SwitchStatement(sw) => sw + .cases + .iter() + .for_each(|c| c.consequent.iter().for_each(|s| assigned_names(s, out))), + Statement::ReturnStatement(r) => { + if let Some(a) = r.argument.as_ref() { + expr(a, out); + } + } + _ => {} + } +} + +fn collect_branches<'b, 'a>(e: &'b Expression<'a>, out: &mut Vec<&'b Expression<'a>>) { + match e { + Expression::ConditionalExpression(c) => { + collect_branches(&c.consequent, out); + collect_branches(&c.alternate, out); + } + Expression::ParenthesizedExpression(p) => collect_branches(&p.expression, out), + // `return sideEffect(…), value` — a comma expression's value is its LAST element. + // The minifier uses it constantly to fold a call in before returning the object + // (`return c || C(chat, u, tag), u`), so taking the whole sequence as the shape + // finds no object at all. + Expression::SequenceExpression(seq) => { + if let Some(last) = seq.expressions.last() { + collect_branches(last, out); + } + } + other => out.push(other), + } +} + +/// The `var x = ` bindings of one statement list, so a result object that names a +/// local (`{ id: n }` after `var n = jidToWid(child.attrGroupJid("jid"))`) still resolves +/// to the wire read behind it. WA's minifier hoists nearly every accessor into a local, +/// so without this most helper-built shapes would read as fieldless. +type Scope<'b, 'a> = HashMap<&'b str, &'b Expression<'a>>; + +/// A result shape together with the bindings in force where it is returned. +type Shape<'b, 'a> = (&'b Expression<'a>, Scope<'b, 'a>); + +/// Follow a bare identifier through the scope to the expression bound to it. Bounded so +/// a self-referential minified binding can't loop. +fn deref_ident<'b, 'a>(e: &'b Expression<'a>, scope: &Scope<'b, 'a>) -> &'b Expression<'a> { + let mut cur = e; + for _ in 0..4 { + let Some(name) = as_identifier(cur) else { + return cur; + }; + match scope.get(name) { + Some(bound) if !std::ptr::eq(*bound, cur) => cur = bound, + _ => return cur, + } + } + cur +} + +/// Turn one arm result shape into the action(s) it can produce. +/// +/// A shape that *delegates wholesale* to a module-local helper (`case UNLINK: return +/// I(child)`) is not one action: the helper branches, and its branches can be different +/// actions — `I` returns `delete_parent_group_unlink`, `integrity_parent_group_unlink` +/// and the sub-group variants depending on `unlink_type` and `unlink_reason`. Folding +/// them into one definition keeps whichever `actionType` resolved first and silently +/// drops the rest, so the helper's branches are expanded into sibling shapes and run +/// through the same merge-by-`actionType` grouping the switch arms use. +/// +/// A helper called in *value position* (`participants: y(chat, child, tag)`) is a +/// different thing — it contributes fields to the enclosing action — and keeps being +/// folded in by [`fold_object`]. +fn expand_shape( + wire_tag: &str, + result: &Expression, + scope: &Scope, + ctx: &ArmCtx, + depth: u8, +) -> Vec { + if depth <= MAX_INLINE_DEPTH + && let Some(src) = local_call_source(deref_ident(result, scope), ctx) + { + let expanded = expand_helper(wire_tag, &src.0, &src.1, ctx, depth + 1); + if !expanded.is_empty() { + return expanded; + } + } + vec![read_action(wire_tag.to_string(), result, scope, ctx, depth)] +} + +/// The helper source, immediately applied to its call-site arguments when one of them is +/// itself a wire read. +/// +/// Applied ONLY in that case. A helper handed the NODE (`y(chat, child, tag)` — the +/// overwhelmingly common form) already works: its body reads off its own parameter and +/// `find_accessor` finds that structurally. Binding those formals to call-site +/// identifiers that do not exist in this parse resolves them to nothing, and doing it +/// unconditionally cost 62 shape elements. The value-passing form is the one that needs +/// the binding. +fn apply_args(fn_src: &str, arg_srcs: &[String]) -> String { + let passes_a_read = arg_srcs + .iter() + .any(|a| a.contains(".attr") || a.contains(".maybeAttr") || a.contains(".content")); + if passes_a_read { + format!("(({fn_src})({}))", arg_srcs.join(", ")) + } else { + format!("({fn_src})") + } +} + +/// Split a parsed `((fn)(a, b))` into the function and a scope binding its formals to +/// the call-site argument expressions. +/// +/// Both live in the SAME allocator (the arguments were re-parsed from their source text +/// alongside the helper), which is what makes the binding expressible at all — a +/// call-site AST node from the enclosing parse could not cross into here. +fn applied_helper<'b, 'a>(e: &'b Expression<'a>) -> (&'b Expression<'a>, Scope<'b, 'a>) { + let mut scope = Scope::new(); + // The wrapper is `((fn)(args))`, so the outer parens hide the call. + let e = match e { + Expression::ParenthesizedExpression(p) => &p.expression, + other => other, + }; + let Some(call) = as_call(e) else { + return (e, scope); + }; + let func = &call.callee; + let params = match func { + Expression::ParenthesizedExpression(p) => function_params(&p.expression), + other => function_params(other), + }; + for (i, name) in params.into_iter().enumerate() { + if let Some(arg) = call.arguments.get(i).and_then(arg_expr) { + scope.insert(name, arg); + } + } + match func { + Expression::ParenthesizedExpression(p) => (&p.expression, scope), + other => (other, scope), + } +} + +/// The formal parameter names of a function expression / declaration. +fn function_params<'b, 'a>(e: &'b Expression<'a>) -> Vec<&'b str> { + let items = match e { + Expression::FunctionExpression(f) => &f.params.items, + Expression::ArrowFunctionExpression(f) => &f.params.items, + _ => return Vec::new(), + }; + items + .iter() + .filter_map(|p| p.pattern.get_identifier_name().map(|n| n.as_str())) + .collect() +} + +/// Parse a helper and expand each of its result branches, inside this parse's own +/// allocator (only the owned definitions escape). +fn expand_helper( + wire_tag: &str, + fn_src: &str, + arg_srcs: &[String], + ctx: &ArmCtx, + depth: u8, +) -> Vec { + let alloc = Allocator::default(); + let wrapped = apply_args(fn_src, arg_srcs); + let ret = wa_oxc::parse_cjs(&alloc, &wrapped); + if ret.panicked { + return Vec::new(); + } + let Some(func) = ret.program.body.iter().find_map(|s| match s { + Statement::ExpressionStatement(es) => Some(&es.expression), + _ => None, + }) else { + return Vec::new(); + }; + let (func, bound) = applied_helper(func); + let mut merged: Vec = Vec::new(); + for (shape, scope) in fn_result_shapes(func, &bound) { + for action in expand_shape(wire_tag, shape, &scope, ctx, depth) { + match merged + .iter_mut() + .find(|g| g.def.action_type == action.action_type) + { + Some(fold) => fold.absorb(action), + None => merged.push(BranchFold::new(action)), + } + } + } + merged.into_iter().map(BranchFold::finish).collect() +} + +/// Read one arm result shape into a [`NotifActionDef`]. +/// +/// The shape is an object literal, a `babelHelpers.extends(a, b, …)` of several, or a +/// call to a module-local helper that builds one (`return T(chat, child, author)`) — +/// all three are folded into the same definition. +fn read_action<'b, 'a>( + wire_tag: String, + result: &'b Expression<'a>, + scope: &Scope<'b, 'a>, + ctx: &ArmCtx, + depth: u8, +) -> NotifActionDef { + let mut def = empty_action(wire_tag); + fold_shape(result, scope, &mut def, ctx, depth); + def.constant_fields.sort_by(|a, b| a.name.cmp(&b.name)); + def +} + +/// Fold one result expression's contribution into `def`. +fn fold_shape<'b, 'a>( + e: &'b Expression<'a>, + scope: &Scope<'b, 'a>, + def: &mut NotifActionDef, + ctx: &ArmCtx, + depth: u8, +) { + if depth > MAX_INLINE_DEPTH { + return; + } + let e = deref_ident(e, scope); + match e { + Expression::ParenthesizedExpression(p) => fold_shape(&p.expression, scope, def, ctx, depth), + // `babelHelpers.extends(objLiteral, helper(child), …)` — every argument + // contributes; WA uses it precisely to merge a helper's fields into an arm. + Expression::CallExpression(c) if callee_method(c) == Some("extends") => { + for arg in &c.arguments { + if let Some(inner) = arg_expr(arg) { + fold_shape(inner, scope, def, ctx, depth + 1); + } + } + } + Expression::ObjectExpression(_) => fold_object(e, scope, def, ctx, depth), + _ => { + // A helper whose whole result is a repeated element (`return + // child.mapChildrenWithTag("participant", …)` — where every participant + // list lives). The caller names it after the key it was bound to. + if let Some(child) = mapped_child("", e, scope, ctx.consts) { + def.children.push(child); + } else if let Some(src) = local_call_source(e, ctx) { + inline_local(&src.0, &src.1, def, ctx, depth); + } + } + } +} + +/// How deep a chain of helper inlinings is followed. Three is enough for every observed +/// arm (`arm → participants helper → per-participant object`) and bounds a cycle. +const MAX_INLINE_DEPTH: u8 = 3; + +/// The source of the module-local helper `e` calls, if it is one. +fn local_call_source(e: &Expression, ctx: &ArmCtx) -> Option<(String, Vec)> { + let call = as_call(e)?; + let name = as_identifier(&call.callee)?; + let src = ctx.locals.get(name).cloned()?; + // The argument TEXT, so `inline_local` can bind the helper's formals. A span outside + // the module source (a synthesized node) yields nothing for that position rather than + // a wrong slice. + let args = call + .arguments + .iter() + .map(|a| { + arg_expr(a) + .map(oxc_span::GetSpan::span) + .and_then(|sp| ctx.source.get(sp.start as usize..sp.end as usize)) + .unwrap_or("") + .to_string() + }) + .collect(); + Some((src, args)) +} + +/// Re-parse a helper's source and fold each of its result branches into `def`. +/// +/// The inlining happens inside this parse's own allocator, so no AST reference escapes +/// it — the helper's contribution is accumulated straight into `def`. +fn inline_local( + fn_src: &str, + arg_srcs: &[String], + def: &mut NotifActionDef, + ctx: &ArmCtx, + depth: u8, +) { + let alloc = Allocator::default(); + // Wrapped in parens so a `function name(…){…}` declaration parses as an expression, + // and IMMEDIATELY APPLIED to the call site's argument text. A helper that only reads + // off a node it is handed works either way, but one that receives an already-read + // VALUE (`function h(v){ return {id: v} }` called as `h(child.attrString("jid"))`) + // resolves its parameter to nothing without this, and the field is lost. + let wrapped = apply_args(fn_src, arg_srcs); + let ret = wa_oxc::parse_cjs(&alloc, &wrapped); + if ret.panicked { + return; + } + let Some(func) = ret.program.body.iter().find_map(|s| match s { + Statement::ExpressionStatement(es) => Some(&es.expression), + _ => None, + }) else { + return; + }; + let (func, bound) = applied_helper(func); + // Each of the helper's result branches is folded on its own and then MERGED, not + // accumulated: a helper returning `{x: …}` in one branch and `{y: …}` in another + // describes two legal shapes, and combining them would make the enclosing action + // require both and reject either. `merge_action` weakens what only some branches + // carry — the same rule the switch arms use. + let mut branches: Vec = Vec::new(); + for (shape, scope) in fn_result_shapes(func, &bound) { + let mut one = empty_action(String::new()); + fold_shape(shape, &scope, &mut one, ctx, depth + 1); + match branches + .iter_mut() + .find(|b| b.def.action_type == one.action_type) + { + Some(fold) => fold.absorb(one), + None => branches.push(BranchFold::new(one)), + } + } + let branches: Vec = branches.into_iter().map(BranchFold::finish).collect(); + // Distinct action types cannot arise here (a value-position helper contributes + // fields, it does not pick the action), so folding the merged branches in is safe. + for b in branches { + merge_into(def, b); + } +} + +/// Fold a helper's contribution into the enclosing action, keeping what the enclosing +/// object already stated and weakening nothing it owns. +/// One key's value in an action shape, in whichever of the three forms it takes. +/// +/// The three collections are three *representations* of one namespace — a shape's keys — +/// not three independent namespaces. Modelling them separately is what let a key exist +/// twice in different forms. +enum KeyValue { + Field(NotifActionField), + Child(NotifActionChild), + Const(NotifConstValue), +} + +/// Write `key` into `def`, last write wins across **all three** collections. +/// +/// The eviction is the point. Each collection used to replace only within itself, so +/// `extends({id: child.attrString("jid")}, {id: 0})` — which yields just `id: 0` at +/// runtime — published a wire-read field *and* a constant both named `id`, and the +/// reverse order left the stale constant behind. A later write does not merely shadow an +/// earlier one; it replaces it, whatever form the earlier one took. +fn write_key(def: &mut NotifActionDef, key: &str, value: KeyValue) { + def.fields.retain(|x| x.name != key); + def.children.retain(|x| x.name != key); + def.constant_fields.retain(|x| x.name != key); + match value { + KeyValue::Field(f) => def.fields.push(f), + KeyValue::Child(c) => def.children.push(c), + KeyValue::Const(v) => def.constant_fields.push(NotifActionConstant { + name: key.to_string(), + value: v, + }), + } +} + +/// Fold a helper's result into `def` as an `babelHelpers.extends` operand. +/// +/// A helper contributes at ITS position in the argument list, so everything it writes — +/// `actionType` included — overrides what an earlier operand wrote, the same last-write +/// rule an object literal follows. Keeping `actionType` on first-write meant +/// `extends({actionType: A}, helper())` where the helper returns `B` dispatched as `A`. +fn merge_into(def: &mut NotifActionDef, from: NotifActionDef) { + if from.action_type.is_some() { + def.action_type = from.action_type; + } + for f in from.fields { + let key = f.name.clone(); + write_key(def, &key, KeyValue::Field(f)); + } + for c in from.children { + let key = c.name.clone(); + write_key(def, &key, KeyValue::Child(c)); + } + for c in from.constant_fields { + write_key(def, &c.name.clone(), KeyValue::Const(c.value)); + } +} + +/// The statement list of a function expression / declaration. +fn function_body_of<'b, 'a>(e: &'b Expression<'a>) -> Option<&'b [Statement<'a>]> { + match e { + Expression::ParenthesizedExpression(p) => function_body_of(&p.expression), + Expression::FunctionExpression(f) => f.body.as_ref().map(|b| b.statements.as_slice()), + Expression::ArrowFunctionExpression(f) => Some(f.body.statements.as_slice()), + _ => None, + } +} + +/// Read the `{ key: value, … }` properties of one result shape into `def`. +fn fold_object<'b, 'a>( + obj: &'b Expression<'a>, + scope: &Scope<'b, 'a>, + def: &mut NotifActionDef, + ctx: &ArmCtx, + depth: u8, +) { + let Some(o) = wa_oxc::as_object(obj) else { + return; + }; + // `obj_props` skips a spread, so folding the survivors publishes a partial shape: + // `{id: attrString("jid"), ...{id: attrString("lid")}}` yields `lid` at runtime and + // `jid` here. Same rule the constant tables and the enum tables already follow — a + // shape that cannot be read whole is refused rather than half-reported. + if o.properties.len() != wa_oxc::obj_props(o).count() { + return; + } + for (key, value) in wa_oxc::obj_props(o) { + // The normalised action identity. Resolved through the const table, so the + // many-to-one mapping (`not_ephemeral` → `ephemeral`) is recorded as WA means + // it, not as the case label suggests. `None` when the arm computes it (e.g. + // `link` selects between three actions by its own `link_type` attribute) — + // recorded as unknown rather than guessed. + let value = deref_ident(value, scope); + // Last write wins for EVERY key a shape writes, not just the scalar fields: + // `extends({actionType: A}, {actionType: B})` and `{duration: 0, duration: 1}` + // both yield the later value at runtime. Fixing this for one kind of key and + // leaving `actionType` and the constants on first-write was the same rule + // written in three places again. + if key == "actionType" { + // A shape may write the normalised identity directly (`{actionType: "create"}`) + // instead of through the constant table. The resolver only accepts + // `o("Mod").OBJECT.MEMBER`, so a fully static literal came back `None` and the + // arm published no `actionType` at all — indistinguishable from an identity + // the arm genuinely computes. + def.action_type = as_string_lit(value) + .map(str::to_string) + .or_else(|| ctx.consts.resolve(value)); + continue; + } + if let Some(c) = const_value(value) { + write_key(def, key, KeyValue::Const(c)); + continue; + } + if let Some(child) = mapped_child(key, value, scope, ctx.consts) { + write_key(def, key, KeyValue::Child(child)); + continue; + } + // A helper call in value position (`participants: y(chat, child, tag)`): inline + // it under this key — that is where every participant list actually lives. + if let Some(src) = local_call_source(strip_guard(value), ctx) + && depth < MAX_INLINE_DEPTH + { + let mut nested = empty_action(String::new()); + inline_local(&src.0, &src.1, &mut nested, ctx, depth); + // A helper that yields nothing is a helper the inliner cannot see through — + // typically because the value arrives through a PARAMETER + // (`reason: hasAttr("reason") ? S(t.attrString("reason")) : null`, where `S` + // normalises the string it is handed). Its body reads no wire attribute of its + // own, so inlining produced an empty shape and the key was dropped, live for + // `add`, `remove` and `delete`'s `reason`. + // + // Falling through to `read_field` recovers it: the wire read is in the CALL's + // arguments, which `find_accessor` already descends into — and it refuses the + // key outright if two arguments disagree. + if nested.children.is_empty() && nested.fields.is_empty() { + if let Some(field) = read_field(key, value, scope, ctx.consts) { + write_key(def, key, KeyValue::Field(field)); + } + continue; + } + // A helper whose result is a repeated element becomes this key's child list; + // one that returns a flat object contributes its fields under their own names. + for mut c in nested.children { + c.name = key.to_string(); + write_key(def, key, KeyValue::Child(c)); + } + for f in nested.fields { + let fkey = f.name.clone(); + write_key(def, &fkey, KeyValue::Field(f)); + } + continue; + } + if let Some(field) = read_field(key, value, scope, ctx.consts) { + // Last write wins WITHIN one shape: a duplicate key in an object literal, and + // a later `babelHelpers.extends(…)` operand, both override at runtime — + // `extends({id: attrString("jid")}, {id: attrString("lid")})` yields `lid`. + // (Between mutually exclusive BRANCHES the rule is the opposite: they merge, + // and a genuine disagreement is refused. See `merge_fields`.) + write_key(def, key, KeyValue::Field(field)); + } + } +} + +/// A literal an arm stamps unconditionally (`value: !0`, `duration: 0`, `type: "x"`). +fn const_value(e: &Expression) -> Option { + match e { + Expression::BooleanLiteral(b) => Some(NotifConstValue::Bool(b.value)), + Expression::StringLiteral(s) => Some(NotifConstValue::Str(s.value.to_string())), + // The minifier writes booleans as `!0` / `!1`. + Expression::UnaryExpression(u) if u.operator == oxc_ast::ast::UnaryOperator::LogicalNot => { + as_int(&u.argument).map(|n| NotifConstValue::Bool(n == 0)) + } + _ => as_int(e).map(NotifConstValue::Int), + } +} + +/// `child.mapChildrenWithTag("participant", function (p) { … })` → the repeated +/// sub-element and the fields read off each one. +fn mapped_child<'b, 'a>( + key: &str, + e: &'b Expression<'a>, + scope: &Scope<'b, 'a>, + consts: &ConstResolver, +) -> Option { + let call = as_call(strip_guard(e))?; + if callee_method(call)? != wap::MAP_CHILDREN_WITH_TAG { + return None; + } + let wire_tag = arg_expr(call.arguments.first()?).and_then(as_string_lit)?; + let mut fields = Vec::new(); + for arg in &call.arguments { + if let Some(e) = arg_expr(arg) { + collect_accessor_fields(e, scope, consts, &mut fields); + } + } + Some(NotifActionChild { + name: key.to_string(), + wire_tag: wire_tag.to_string(), + fields, + }) +} + +/// Read a single output field from the expression bound to `key`. +/// +/// Handles the four shapes an arm uses: a bare accessor (`child.attrString("subject")`), +/// a presence guard (`child.hasAttr("reason") ? f(child.attrString("reason")) : null`), +/// a null-coalesce (`(x = child.maybeAttrString("t")) != null ? x : d`), and a content +/// read (`child.child("body").contentString()`). Anything else — a computed value with +/// no single wire source — yields `None` rather than a guessed name. +fn read_field<'b, 'a>( + key: &str, + e: &'b Expression<'a>, + scope: &Scope<'b, 'a>, + consts: &ConstResolver, +) -> Option { + let e = deref_ident(e, scope); + // A ternary between two REAL values is not a presence guard, and treating every + // conditional as one kept the consequent and threw the alternate away: + // `{id: cond ? child.attrString("jid") : child.attrString("lid")}` published an + // optional `jid` and lost `lid` entirely — or lost the field altogether when only + // the alternate read the wire. + if let Some(v) = value_selection(key, e, scope, consts) { + return v; + } + let optional_by_guard = is_guarded(e); + let acc = find_accessor(strip_guard(e), scope)?; + let enum_ref = consts.action_enum_ref(&acc.method, acc.enum_arg, &acc.wire_name); + Some(NotifActionField { + name: key.to_string(), + wire_name: acc.wire_name, + field_type: wap::method_field_type(&acc.method), + required: !optional_by_guard && !wap::is_optional_method(&acc.method), + content: acc.content, + enum_ref, + }) +} + +/// Resolve a `cond ? a : b` whose branches are two real values rather than a value and +/// an absence. +/// +/// Returns `None` when this is not that shape (a plain guard, or not a ternary), so the +/// caller falls through to its normal handling. `Some(None)` means the key is **refused**. +/// +/// The three outcomes follow the rule the branch fold already uses elsewhere: +/// * one side nullish → a presence guard, whichever side reads the wire, optional; +/// * both sides the same wire read → that read; +/// * two different wire reads → refused, because one output key cannot name two wire +/// attributes and picking the consequent is a coin flip the IR would state as fact. +fn value_selection<'b, 'a>( + key: &str, + e: &'b Expression<'a>, + scope: &Scope<'b, 'a>, + consts: &ConstResolver, +) -> Option> { + let Expression::ConditionalExpression(c) = e else { + return None; + }; + // The null-coalesce idiom `(x = maybeAttrString("t")) != null ? x : void 0` hides the + // read in the TEST; `strip_guard` already resolves it, and it is a guard, not a + // selection. Leave it alone. + if as_identifier(strip_guard(&c.consequent)) + .and_then(|n| assigned_in(&c.test, n)) + .is_some() + { + return None; + } + let (a, b) = (strip_guard(&c.consequent), strip_guard(&c.alternate)); + let (ra, rb) = (find_accessor(a, scope), find_accessor(b, scope)); + match (ra, rb) { + // Only one side reads the wire: a presence guard in whichever direction it is + // written. `cond ? null : child.attrString("x")` is as common as the other order + // and used to lose the field completely. + (Some(acc), None) if is_nullish(b) => Some(Some(guarded_field(key, acc, consts))), + (None, Some(acc)) if is_nullish(a) => Some(Some(guarded_field(key, acc, consts))), + (Some(x), Some(y)) => { + if x.wire_name == y.wire_name && x.method == y.method && x.content == y.content { + // The SAME read on both paths runs on every execution, so it keeps the + // accessor's own requiredness. Falling through to the plain path made + // `read_field` see a conditional, call it a presence guard, and publish + // `required: false` for an accessor that still rejects an absent value. + Some(Some(NotifActionField { + name: key.to_string(), + required: !wap::is_optional_method(&x.method), + field_type: wap::method_field_type(&x.method), + wire_name: x.wire_name, + content: x.content, + enum_ref: x.enum_arg.and_then(|a| consts.enum_ref(a)), + })) + } else { + Some(None) // two sources for one key: refuse + } + } + _ => None, + } +} + +/// Whether the expression is a literal absence — the far side of a presence guard. +fn is_nullish(e: &Expression) -> bool { + match e { + Expression::NullLiteral(_) => true, + Expression::Identifier(i) => i.name == "undefined", + // The minifier writes `undefined` as `void 0`. + Expression::UnaryExpression(u) => u.operator == oxc_ast::ast::UnaryOperator::Void, + _ => false, + } +} + +/// The field an accessor yields when it sits behind a presence guard: always optional, +/// because the guard exists precisely so the attribute may be absent. +fn guarded_field(key: &str, acc: Accessor, consts: &ConstResolver) -> NotifActionField { + let enum_ref = consts.action_enum_ref(&acc.method, acc.enum_arg, &acc.wire_name); + NotifActionField { + name: key.to_string(), + wire_name: acc.wire_name, + field_type: wap::method_field_type(&acc.method), + required: false, + content: acc.content, + enum_ref, + } +} + +/// Whether the value is read behind a presence guard, so the attribute may be absent. +/// +/// A ternary and a `guard && value` both gate the read on something. `a || b` / `a ?? b` +/// do NOT: the accessor on the left runs unconditionally and `attrString` still rejects +/// an absent attribute — the right operand only supplies a default for a value the +/// parser already required. Treating those as guards marked required fields optional. +fn is_guarded(e: &Expression) -> bool { + match e { + Expression::ConditionalExpression(_) => true, + Expression::LogicalExpression(l) => { + l.operator == oxc_syntax::operator::LogicalOperator::And + } + _ => false, + } +} + +/// The value branch of a `cond ? value : fallback` / `a || b` guard, else `e` itself. +/// +/// The minifier's null-coalesce idiom hides the accessor in the *test*: +/// `(x = child.maybeAttrString("threshold")) != null ? x : void 0`. The consequent is +/// then a bare `x` that no declaration binds, so following it alone loses the field +/// (`locked`'s `threshold` vanished exactly this way). When the consequent is an +/// identifier assigned inside the test, the assignment's right-hand side is the value. +fn strip_guard<'b, 'a>(e: &'b Expression<'a>) -> &'b Expression<'a> { + match e { + Expression::ConditionalExpression(c) => { + let value = strip_guard(&c.consequent); + match as_identifier(value).and_then(|name| assigned_in(&c.test, name)) { + Some(assigned) => strip_guard(assigned), + None => value, + } + } + Expression::ParenthesizedExpression(p) => strip_guard(&p.expression), + // `guard && value` puts the value on the RIGHT — taking the left yields the + // `hasAttr` test, which is deliberately not a wire accessor, so the field would + // vanish. `a || b` / `a ?? b` are the opposite: the left IS the value and the + // right only defaults it. + Expression::LogicalExpression(l) => match l.operator { + oxc_syntax::operator::LogicalOperator::And => strip_guard(&l.right), + _ => strip_guard(&l.left), + }, + Expression::AssignmentExpression(a) => strip_guard(&a.right), + _ => e, + } +} + +/// The right-hand side of an `name = ` assignment somewhere inside `e`. +fn assigned_in<'b, 'a>(e: &'b Expression<'a>, name: &str) -> Option<&'b Expression<'a>> { + match e { + Expression::AssignmentExpression(a) => { + let target = a.left.get_identifier_name().map(|n| n.to_string()); + if target.as_deref() == Some(name) { + Some(&a.right) + } else { + assigned_in(&a.right, name) + } + } + Expression::ParenthesizedExpression(p) => assigned_in(&p.expression, name), + Expression::BinaryExpression(b) => { + assigned_in(&b.left, name).or_else(|| assigned_in(&b.right, name)) + } + Expression::LogicalExpression(l) => { + assigned_in(&l.left, name).or_else(|| assigned_in(&l.right, name)) + } + Expression::UnaryExpression(u) => assigned_in(&u.argument, name), + _ => None, + } +} + +/// The innermost wap accessor call in `e` → `(method, wireName, isContentRead)`. +/// +/// Descends through the wrapper calls an arm applies to a raw wire value +/// (`userJidToUserWid(child.attrUserJid("jid"))`, `S(child.attrString("reason"))`), and +/// through a `child("body").contentString()` chain — where the *tag* is the wire name, +/// since a content read has no attribute of its own. +fn find_accessor<'b, 'a>(e: &'b Expression<'a>, scope: &Scope<'b, 'a>) -> Option> { + find_accessor_at(e, scope, 0) +} + +/// A resolved wire read: the accessor method, the attribute (or child tag) it reads, +/// whether it is a content read, and the enum argument it validates against, if any. +struct Accessor<'b, 'a> { + method: String, + wire_name: String, + content: bool, + enum_arg: Option<&'b Expression<'a>>, +} + +/// How deep the wrapper-call descent goes. Bounded like every other descent in this +/// module: mutually referential minified bindings (`var a = g(b), b = g(a)` — legal JS, +/// and the minifier reuses short names aggressively) would otherwise cycle through +/// `deref_ident` and blow the stack, turning a bundle shape into a hard crash of the +/// generator instead of a field that simply isn't recovered. +const MAX_ACCESSOR_DEPTH: u8 = 8; + +fn find_accessor_at<'b, 'a>( + e: &'b Expression<'a>, + scope: &Scope<'b, 'a>, + depth: u8, +) -> Option> { + if depth > MAX_ACCESSOR_DEPTH { + return None; + } + let call = as_call(deref_ident(e, scope))?; + if let Some(method) = callee_method(call) { + let arg0 = call.arguments.first().and_then(arg_expr); + let name = arg0.and_then(as_string_lit); + if let Some(name) = name + && is_wire_accessor(method) + { + return Some(Accessor { + method: method.to_string(), + wire_name: name.to_string(), + content: false, + enum_arg: enum_table_arg(method, call, scope), + }); + } + // A content read — `X.contentString()`, `X.contentUint()`, … — takes no attribute + // name, so the wire name is the tag of whatever `X` descends to, and `""` when it + // reads the arm's own node. Asking `wap` rather than listing spellings here is + // what keeps a newly classified accessor from being silently dropped. + if wap::is_content_method(method) { + // The receiver is often hoisted (`var body = child.child("body"); … body + // .contentString()`), so it must be dereferenced through the scope first — + // otherwise the wire name comes out empty and a consumer cannot tell content + // read from a nested child apart from content read on the action node. + let tag = wa_oxc::callee_object(call) + .map(|obj| deref_ident(obj, scope)) + .and_then(as_call) + .and_then(|inner| inner.arguments.first().and_then(arg_expr)) + .and_then(as_string_lit) + .unwrap_or_default(); + return Some(Accessor { + method: method.to_string(), + wire_name: tag.to_string(), + content: true, + // `node.contentEnum(TABLE)` validates against a table just as the + // attribute path does; hardcoding `None` here typed the field as an enum + // while denying a consumer its legal values. + enum_arg: enum_table_arg(method, call, scope), + }); + } + } + // A wrapper call (`userJidToUserWid(…)`, a local normaliser): look inside. + // + // Exactly one argument may read the wire. `combine(c.attrString("a"), + // c.attrString("b"))` derives its value from both, and a `NotifActionField` names one + // `wireName` with one requiredness — so taking whichever came first would state as + // fact something the IR cannot express. Refused instead, the same rule a key bound to + // two different reads across branches already follows. + // EVERY argument is inspected, not just the second: `combine(a("jid"), a("jid"), + // a("lid"))` matches on the second and conflicts on the third, and stopping early + // published `jid` again for a value that also depends on `lid`. + let mut found = call + .arguments + .iter() + .filter_map(arg_expr) + .filter_map(|a| find_accessor_at(a, scope, depth + 1)); + let first = found.next()?; + // A repeated read of the SAME attribute is not ambiguous — a normaliser given the + // same value twice still has one source. + let conflicts = found.any(|a| a.wire_name != first.wire_name || a.method != first.method); + (!conflicts).then_some(first) +} + +/// The enum table an enum-valued accessor validates against. +/// +/// Gated on the shared classifier rather than a list of spellings, and applied to the +/// attribute and content paths alike — `maybeAttrEnum("type", o("Mod").TABLE)`, +/// `attrEnumOrNullIfUnknown("reason", v)` (hoisted into a local, so the candidate is +/// dereferenced first) and `contentEnum(TABLE)` are the same constraint written three +/// ways. `None` for a non-enum accessor. +fn enum_table_arg<'b, 'a>( + method: &str, + call: &'b oxc_ast::ast::CallExpression<'a>, + scope: &Scope<'b, 'a>, +) -> Option<&'b Expression<'a>> { + if wap::method_field_type(method) != wa_ir::ParsedFieldType::Enum { + return None; + } + call.arguments + .iter() + .filter_map(arg_expr) + .map(|a| deref_ident(a, scope)) + .find(|a| as_member(a).is_some()) +} + +/// Whether `method` is a wap accessor that reads a named wire attribute. Keyed on the +/// accessor prefix rather than an exhaustive list so a new JID/time flavour is covered +/// automatically; `hasAttr` is excluded because it is the *guard*, not the read. +fn is_wire_accessor(method: &str) -> bool { + (method.starts_with("attr") || method.starts_with("maybeAttr")) && method != wap::HAS_ATTR +} + +/// Collect every wire accessor reachable inside a mapped-child callback, as fields. +/// Order follows source order; duplicates (the same attribute read twice, e.g. once for +/// a derived flag) are folded into the first occurrence. +fn collect_accessor_fields<'b, 'a>( + e: &'b Expression<'a>, + outer: &Scope<'b, 'a>, + consts: &ConstResolver, + out: &mut Vec, +) { + // No whole-body pre-pass. `collect_returns` installs the callback's own `var` + // bindings in STATEMENT ORDER, which is the same rule it already documents for the + // top level: hoisting moves the declaration, not the assignment, so snapshotting the + // whole body made a later initializer visible to an earlier return — + // `if (c) return {id: x}; var x = item.attrString("late")` published a wire + // dependency on `late` for a branch that runs before it exists. + let scope = outer.clone(); + // Only function arguments hold the per-element shape; a bare expression contributes + // nothing (the tag string, the bounds). + if !matches!( + e, + Expression::FunctionExpression(_) | Expression::ArrowFunctionExpression(_) + ) { + return; + } + // Per RETURN SHAPE, then merged — the same rule the action arms and the value-position + // helpers use. A callback that returns different objects from an `if` or a ternary + // describes alternative element shapes: flattening every property in the body into + // one list would mark a field read in only one branch as required, and let two + // branches reusing an output name silently keep whichever came first. + let mut merged: Vec = Vec::new(); + let mut dead = Conflicts::new(); + let mut branches = 0usize; + for (shape, inner) in fn_result_shapes(e, &scope) { + branches += 1; + let mut fields = Vec::new(); + collect_shape_fields(shape, &inner, consts, &mut fields); + merge_fields(&mut merged, fields, branches == 1, &mut dead); + } + apply_conflicts(&mut merged, &dead); + // A callback that returns a bare value rather than an object + // (`p => userJidToUserWid(p.attrUserJid("jid"))`) has no property key to name the + // field by, so the wire attribute names it — better than reporting no fields at all. + // It goes through `merge_fields` too, one field set per return shape. Appending each + // read directly bypassed the branch fold, so `p => cond ? p.attrString("jid") : + // p.attrString("lid")` reported BOTH as required when each execution reads one. + if merged.is_empty() { + let mut bare = 0usize; + for (shape, inner) in fn_result_shapes(e, &scope) { + bare += 1; + let fields = find_accessor(shape, &inner) + .map(|acc| { + let enum_ref = + consts.action_enum_ref(&acc.method, acc.enum_arg, &acc.wire_name); + NotifActionField { + name: acc.wire_name.clone(), + wire_name: acc.wire_name, + field_type: wap::method_field_type(&acc.method), + required: !wap::is_optional_method(&acc.method), + content: acc.content, + enum_ref, + } + }) + .into_iter() + .collect(); + merge_fields(&mut merged, fields, bare == 1, &mut dead); + } + apply_conflicts(&mut merged, &dead); + } + for f in merged { + if !out.iter().any(|x| x.name == f.name) { + out.push(f); + } + } +} + +/// Every `{ key: }` property reachable in one result shape. +fn collect_shape_fields<'b, 'a>( + shape: &'b Expression<'a>, + scope: &Scope<'b, 'a>, + consts: &ConstResolver, + out: &mut Vec, +) { + struct Walker<'o, 'b, 'a> { + scope: &'o Scope<'b, 'a>, + consts: &'o ConstResolver<'o>, + out: &'o mut Vec, + } + impl<'b, 'a> Visit<'a> for Walker<'_, 'b, 'a> { + fn visit_object_property(&mut self, p: &oxc_ast::ast::ObjectProperty<'a>) { + if let Some(key) = wa_oxc::property_key_name(&p.key) + && let Some(field) = read_field(key, &p.value, self.scope, self.consts) + && !self.out.iter().any(|f| f.name == field.name) + { + self.out.push(field); + } + // Do NOT descend into a property whose value is itself an object literal: + // that is NESTING, not more of this shape. `{meta: {id: p.attrString("id")}}` + // has no top-level `id`, and walking in claimed each element had one. The walk + // still descends everything else, which is how it reaches the operands of a + // `babelHelpers.extends(…)` wrapper. + if wa_oxc::as_object(deref_ident(&p.value, self.scope)).is_some() { + return; + } + walk::walk_object_property(self, p); + } + } + let mut w = Walker { scope, consts, out }; + // The minifier almost always builds the object into a local and returns the name + // (`var u = {…}; return sideEffect(), u`), so the returned expression is an + // identifier — walking it directly would find no properties at all. + w.visit_expression(deref_ident(shape, scope)); +} + +/// Names whose wire read two branches disagreed on. A **tombstone**, kept for the whole +/// merge rather than one call of it: with three or more branches, `A(jid)` conflicting +/// with `B(lid)` would remove the key and then `C(jid)` — seeing nothing there — would +/// add it back, so the union would again advertise one source while another legal branch +/// reads a different attribute. +type Conflicts = std::collections::HashSet; + +/// Fold one branch's fields into the accumulated set: a field either branch reads is +/// present, and required only when EVERY branch reads it unconditionally. +/// +/// When two branches bind the same output key to **different wire reads**, there is no +/// single answer — reporting the first branch's attribute would describe the other +/// branch's payload wrongly — so the key is tombstoned. Missing, not wrong, as everywhere +/// else in this module. Call [`apply_conflicts`] once the last branch is in. +fn merge_fields( + into: &mut Vec, + from: Vec, + first: bool, + dead: &mut Conflicts, +) { + if !first { + for existing in into.iter_mut() { + if !from.iter().any(|f| f.name == existing.name) { + existing.required = false; + } + } + } + for f in from { + if dead.contains(&f.name) { + continue; + } + match into.iter_mut().find(|x| x.name == f.name) { + Some(existing) if same_wire_read(existing, &f) => existing.required &= f.required, + Some(existing) => { + dead.insert(existing.name.clone()); + } + None => into.push(NotifActionField { + required: f.required && first, + ..f + }), + } + } +} + +/// Drop every tombstoned key. Run after the final branch, never between them. +fn apply_conflicts(fields: &mut Vec, dead: &Conflicts) { + fields.retain(|f| !dead.contains(&f.name)); +} + +/// Whether two bindings of the same output key describe the same wire read. +fn same_wire_read(a: &NotifActionField, b: &NotifActionField) -> bool { + a.wire_name == b.wire_name + && a.field_type == b.field_type + && a.content == b.content + && a.enum_ref == b.enum_ref +} diff --git a/crates/wa-notif/src/lib.rs b/crates/wa-notif/src/lib.rs index 5e69631..55f4b54 100644 --- a/crates/wa-notif/src/lib.rs +++ b/crates/wa-notif/src/lib.rs @@ -31,6 +31,8 @@ //! the AST. #![cfg(not(target_arch = "wasm32"))] +mod actions; + use std::collections::HashMap; use oxc_allocator::Allocator; @@ -71,6 +73,17 @@ pub fn extract_notif_from_modules( module_defs: &[ModuleDefinition], wa_version: &str, ) -> NotifIr { + extract_notif_with_diagnostics(source, module_defs, wa_version).0 +} + +/// Like [`extract_notif_from_modules`], but also returns the constraints the handlers' +/// legacy parsers carried and this domain could not resolve, by `dropsByReason` key. +/// See [`wa_scan::scan_incoming_with_diagnostics`] for why they are counted. +pub fn extract_notif_with_diagnostics( + source: &str, + module_defs: &[ModuleDefinition], + wa_version: &str, +) -> (NotifIr, std::collections::BTreeMap) { // Collect each dispatcher once (a module is often defined in several shards). let mut dispatchers: Vec<(String, Dispatch)> = Vec::new(); let mut seen = std::collections::HashSet::new(); @@ -112,6 +125,11 @@ pub fn extract_notif_from_modules( // handler that yields no parser leaves `content` absent (degraded), never // dropping the catalog entry. let slice_by_name = module_slice_index(source, module_defs); + // The legacy parser leaves `o("Mod").ENUM` links pending — it reads one module at a + // time — so this domain runs the same cross-module post-pass the IQ scan does. + // Skipping it did not merely lose the link: the pending marker used to be an + // `enumRef` with no variants, published as "this field admits no value". + let mut enums = wa_scan::ResponseEnumLinker::new(module_defs, source); for n in &mut dispatch.notifications { let Some(module) = n.handler_module.clone() else { continue; @@ -121,6 +139,47 @@ pub fn extract_notif_from_modules( }; let notif_type = n.notif_type.clone(); n.content = notification_content(slice, ¬if_type); + if let Some(content) = &mut n.content { + enums.resolve(&format!("{module}::{notif_type}"), content); + } + } + + // Phase 3: the payload action union. `content` describes the envelope; a handler + // that maps over the notification's children and switches on each child's tag + // carries a whole second union inside it (`w:gp2`'s 40+ group actions). Resolved + // against the full module index, since both the case labels and the `actionType` + // values are `Module.CONST.MEMBER` references defined elsewhere. + // The union is located per MODULE, not per handler function: the switch does not + // live in the exported handler at all — `handleGroupNotification` builds a + // `WADeprecatedWapParser` around a sibling local, and the child-tag switch is inside + // that local. Scoping discovery to the handler's own body would therefore find + // nothing and lose the whole `w:gp2` union. + // + // The cost of module scope is that a module hosting two handlers with two different + // child-tag switches would hand the larger union to both of its notification types. + // No module serves more than one type today, so rather than guess at which switch + // belongs to which handler, a shared module is left without actions — an omission a + // consumer can see, instead of an action union silently attributed to the wrong type. + let mut types_per_module: HashMap = HashMap::new(); + for n in &dispatch.notifications { + if let Some(m) = n.handler_module.clone() { + *types_per_module.entry(m).or_default() += 1; + } + } + let consts = actions::ConstResolver::new(&slice_by_name); + for n in &mut dispatch.notifications { + let Some(module) = n.handler_module.as_deref() else { + continue; + }; + if types_per_module.get(module).copied().unwrap_or(0) > 1 { + continue; + } + let Some(slice) = slice_by_name.get(module) else { + continue; + }; + if let Some(found) = actions::extract_actions(slice, &consts) { + n.actions = found; + } } // Phase 2b: a type still degraded here has a handler that delegates parsing to @@ -134,17 +193,36 @@ pub fn extract_notif_from_modules( if n.content.is_none() && let Some(shape) = srvreq_shapes.get(&n.notif_type) { - n.content = Some(shape.clone()); + let mut shape = shape.clone(); + // This fallback runs after the pass above, so its shapes get resolved + // here — otherwise a link recovered from a server-request read-shape + // would be the one kind that still shipped unfinished. + enums.resolve(&format!("srvreq::{}", n.notif_type), &mut shape); + n.content = Some(shape); } } } - NotifIr { - wa_version: wa_version.to_string(), - dispatcher_modules, - stanza_tags: dispatch.stanza_tags, - notifications: dispatch.notifications, - } + let mut drops = enums.into_drop_counts(); + // The action path has no linker to drain a pending marker, so it reports its own + // unresolvable allowed-value tables here. Without this the `w:gp2` `create.reason` + // field shipped as `"type": "enum"` with no values and nothing anywhere saying a + // constraint had been lost. + let action_enum_drops = consts.take_enum_drops(); + if action_enum_drops > 0 { + *drops + .entry("action enum table not structurally resolvable".to_string()) + .or_default() += action_enum_drops; + } + ( + NotifIr { + wa_version: wa_version.to_string(), + dispatcher_modules, + stanza_tags: dispatch.stanza_tags, + notifications: dispatch.notifications, + }, + drops, + ) } /// Fold one dispatcher's arms into the accumulated catalog. New tags/types are @@ -435,6 +513,7 @@ fn extract_notifications(consequent: &[Statement]) -> Vec { handler_function: handler.and_then(|(_, f)| f), sub_discriminants: Vec::new(), content: None, + actions: Vec::new(), }); } } @@ -450,6 +529,7 @@ fn extract_notification_case(notif_type: &str, consequent: &[Statement]) -> Noti handler_function: handler.and_then(|(_, f)| f), sub_discriminants: extract_sub_discriminants(consequent), content: None, + actions: Vec::new(), } } diff --git a/crates/wa-notif/src/tests.rs b/crates/wa-notif/src/tests.rs index bd9ded5..4db5bd6 100644 --- a/crates/wa-notif/src/tests.rs +++ b/crates/wa-notif/src/tests.rs @@ -564,3 +564,1518 @@ __d("WASmaxInCoexistenceOffboardingNotificationRequest",["WAResultOrError","WASm "an ambiguous type (two read-shapes) must stay degraded" ); } + +/// A miniature `w:gp2` handler: the const tag/action tables in their own modules, and a +/// handler that maps over the notification's children and switches on each child's tag. +/// Reproduces every shape the real one uses — a many-to-one normalisation, a rebound +/// field name, a constant-only arm, a repeated sub-element, and a two-outcome ternary. +const GROUP_ACTIONS_BUNDLE: &str = r#" +__d("WAWebCommsHandleLoggedInStanza",["WAWebHandleGroupNotification","WAWebHandleDeviceNotification"],function(g,r,d,o,e,i,l){ + l.handle = function(){ return (function*(e,t){ + var n = e.attrs; + switch (e.tag) { + case "notification": + switch (n.type) { + case "w:gp2": return yield r("WAWebHandleGroupNotification")(e); + case "devices": return yield o("WAWebHandleDeviceNotification").handleDevicesNotification(e); + } + } + }); }; +}, 1); +__d("WAWebHandleDeviceNotification",["WADeprecatedWapParser"],(function(t,n,r,o,a,i,l){ + var p = new (n("WADeprecatedWapParser"))("incomingDevicesNotification", function(e){ + e.assertTag("notification"); e.assertAttr("type","devices"); + return { id: e.attrString("id") }; + }); + function I(e){ + var t=e.attrString("unlink_type"); + if(t==="parent_group") return {actionType:o("WAWebGroupType").GROUP_ACTIONS.DESC_REMOVE, descId:e.attrString("id")}; + return {actionType:o("WAWebGroupType").GROUP_ACTIONS.DESC_ADD, descId:e.attrString("id")}; + } + function h(e){ return p.parse(e); } + l.handleDevicesNotification = h; +}), 1); +__d("WAWebHandleGroupNotificationConst",[],(function(t,n,r,o,a,i,l){ + var cache={}; + cache.GROUP_NOTIFICATION_TAG={ADD:"WRONG_add",SUBJECT:"WRONG_subject"}; + var e=Object.freeze({ADD:"add",SUBJECT:"subject",EPHEMERAL:"ephemeral",NOT_EPHEMERAL:"not_ephemeral",MODIFY:"modify",GROWTH_LOCKED:"growth_locked",INVITE:"invite",LINK:"link",ANNOUNCE:"announcement",LOCKED:"locked",REVOKE_INVITE:"revoke",DESC:"description",UNLINK:"unlink"}); + l.GROUP_NOTIFICATION_TAG=e; +}), 1); +__d("WAWebGroupApiConst",[],(function(t,n,r,o,a,i,l){ + var g={admin:"admin",superadmin:"superadmin",participant:"participant"}; + l.GROUP_PARTICIPANT_TYPES=g; +}), 1); +__d("WAWebGroupType",[],(function(t,n,r,o,a,i,l){ + var d=Object.freeze({ADD:"add",SUBJECT:"subject",EPHEMERAL:"ephemeral",MODIFY:"modify",ANNOUNCE:"announce",RESTRICT:"restrict",REVOKE_INVITE:"revoke_invite",DESC_ADD:"desc_add",DESC_REMOVE:"desc_remove"}); + l.GROUP_ACTIONS=d; +}), 1); +__d("WAWebHandleGroupNotification",["WAWebHandleGroupNotificationConst","WAWebGroupType"],(function(t,n,r,o,a,i,l){ + function w(e){ if (e.hasChild("a")) return {alpha:e.attrString("alpha")}; return {beta:e.attrString("beta")}; } + function q(e){ return e.mapChildrenWithTag("entry", function(x){ + if (x.hasChild("full")) return {id:x.attrString("id"), extra:x.attrString("extra"), who:x.attrString("jid")}; + if (x.hasChild("mid")) return {id:x.attrString("id"), who:x.attrString("lid")}; + return {id:x.attrString("id"), who:x.attrString("jid")}; + }); } + function q2(e){ + if (e.hasChild("a")) return {actionType:o("WAWebGroupType").GROUP_ACTIONS.ANNOUNCE, rows:e.mapChildrenWithTag("row", function(x){ return {v:x.attrString("p")}; })}; + if (e.hasChild("b")) return {actionType:o("WAWebGroupType").GROUP_ACTIONS.ANNOUNCE, rows:e.mapChildrenWithTag("row", function(x){ return {v:x.attrString("q")}; })}; + return {actionType:o("WAWebGroupType").GROUP_ACTIONS.ANNOUNCE, rows:e.mapChildrenWithTag("row", function(x){ return {v:x.attrString("p")}; })}; + } + function y(e,t){ return t.mapChildrenWithTag("participant", function(p){ + return { id: p.attrUserJid("jid"), displayName: p.maybeAttrString("display_name"), kind: p.maybeAttrEnum("type", o("WAWebGroupApiConst").GROUP_PARTICIPANT_TYPES) }; + }); } + function I(e){ + var t=e.attrString("unlink_type"); + if(t==="parent_group") return {actionType:o("WAWebGroupType").GROUP_ACTIONS.DESC_REMOVE, descId:e.attrString("id")}; + return {actionType:o("WAWebGroupType").GROUP_ACTIONS.DESC_ADD, descId:e.attrString("id")}; + } + function h(e){ + var x = e.mapChildren(function(t){ + var a = t.tag(); + switch(a){ + case o("WAWebHandleGroupNotificationConst").GROUP_NOTIFICATION_TAG.ADD: + return {actionType:o("WAWebGroupType").GROUP_ACTIONS.ADD, participants:y(e,t), reason:t.hasAttr("reason")?t.attrString("reason"):null}; + case o("WAWebHandleGroupNotificationConst").GROUP_NOTIFICATION_TAG.SUBJECT: + if (t.hasChild("delete")) { var n = t.attrString("id"); return {actionType:o("WAWebGroupType").GROUP_ACTIONS.DESC_REMOVE, descId:n}; } + var n = t.attrString("subject"); + return {actionType:o("WAWebGroupType").GROUP_ACTIONS.SUBJECT, subject:n, note:t.hasAttr("note")&&t.attrString("note")}; + case o("WAWebHandleGroupNotificationConst").GROUP_NOTIFICATION_TAG.EPHEMERAL: + return babelHelpers.extends({actionType:o("WAWebGroupType").GROUP_ACTIONS.EPHEMERAL, duration:t.attrInt("expiration"), code:t.attrString("code")||"none"}, w(t)); + case o("WAWebHandleGroupNotificationConst").GROUP_NOTIFICATION_TAG.NOT_EPHEMERAL: + return {actionType:o("WAWebGroupType").GROUP_ACTIONS.EPHEMERAL, duration:0}; + case o("WAWebHandleGroupNotificationConst").GROUP_NOTIFICATION_TAG.MODIFY: { + var z = t.attrString("first"); + if (t.hasChild("early")) return {actionType:o("WAWebGroupType").GROUP_ACTIONS.MODIFY, entries:q(t), pick:z}; + var z = t.attrString("second"); + return {actionType:o("WAWebGroupType").GROUP_ACTIONS.RESTRICT, pick:z}; + } + case o("WAWebHandleGroupNotificationConst").GROUP_NOTIFICATION_TAG.ANNOUNCE: + return q2(t); + case o("WAWebHandleGroupNotificationConst").GROUP_NOTIFICATION_TAG.INVITE: + o("WALogger").INFO("no fall-through"); break; + case o("WAWebHandleGroupNotificationConst").GROUP_NOTIFICATION_TAG.LINK: { + var lt = t.attrString("link_type"); + switch (lt) { + case "parent": return {actionType:o("WAWebGroupType").GROUP_ACTIONS.DESC_ADD, parentId:t.attrString("pid")}; + default: return {actionType:o("WAWebGroupType").GROUP_ACTIONS.DESC_REMOVE, subId:t.attrString("sid")}; + } + } + case o("WAWebHandleGroupNotificationConst").GROUP_NOTIFICATION_TAG.GROWTH_LOCKED: + o("WALogger").INFO("setup"); + var thr = t.attrString("threshold"); + case o("WAWebHandleGroupNotificationConst").GROUP_NOTIFICATION_TAG.LOCKED: { + var n; + return {actionType:o("WAWebGroupType").GROUP_ACTIONS.RESTRICT, value:!0, threshold:(n=t.maybeAttrString("threshold"))!=null?n:void 0, seeded:thr}; + } + case o("WAWebHandleGroupNotificationConst").GROUP_NOTIFICATION_TAG.UNLINK: + return I(t); + case o("WAWebHandleGroupNotificationConst").GROUP_NOTIFICATION_TAG.REVOKE_INVITE: + return {actionType:o("WAWebGroupType").GROUP_ACTIONS.REVOKE_INVITE, participants:t.mapChildrenWithTag("participant", function(p){ return {id:p.attrUserJid("jid"), expiration:p.attrInt("expiration")}; }), owners:t.mapChildrenWithTag("owner", p=>o("WAWebJidToWid").userJidToUserWid(p.maybeAttrPhoneUserJid("phone_number")))}; + case o("WAWebHandleGroupNotificationConst").GROUP_NOTIFICATION_TAG.DESC: + return t.hasChild("delete") ? {actionType:o("WAWebGroupType").GROUP_ACTIONS.DESC_REMOVE, descId:t.attrString("id")} + : {actionType:o("WAWebGroupType").GROUP_ACTIONS.DESC_ADD, descId:t.attrString("id"), desc:t.child("body").contentString()}; + } + }); + return {actions:x}; + } + l.handleGroupNotification=h; +}), 1); +"#; + +/// The `w:gp2` action union, keyed by the wire tag of each arm. +fn group_actions(ir: &wa_ir::NotifIr) -> Vec<&wa_ir::NotifActionDef> { + notif(ir, "w:gp2").actions.iter().collect() +} + +#[test] +fn group_action_union_records_the_many_to_one_tag_mapping() { + let ir = extract_notif(GROUP_ACTIONS_BUNDLE, "2.3000.test"); + let actions = group_actions(&ir); + let of = |tag: &str| { + actions + .iter() + .filter(|a| a.wire_tag == tag) + .collect::>() + }; + // Acceptance criterion: which wire tags map to `ephemeral`, and what each sets. + let eph = of("ephemeral"); + assert_eq!(eph.len(), 1); + assert_eq!(eph[0].action_type.as_deref(), Some("ephemeral")); + let duration = eph[0] + .fields + .iter() + .find(|f| f.name == "duration") + .expect("duration field"); + // The timer arrives in `expiration`, NOT under the output name — the whole point. + assert_eq!(duration.wire_name, "expiration"); + assert_eq!(duration.field_type, wa_ir::ParsedFieldType::Integer); + assert!(duration.required); + // `not_ephemeral` normalises INTO `ephemeral` with a constant 0 — a consumer that + // branches on a `not_ephemeral` action type is writing dead code. + let not_eph = of("not_ephemeral"); + assert_eq!(not_eph.len(), 1); + assert_eq!(not_eph[0].action_type.as_deref(), Some("ephemeral")); + assert!(not_eph[0].fields.is_empty()); + assert_eq!( + not_eph[0].constant_fields, + vec![wa_ir::NotifActionConstant { + name: "duration".into(), + value: wa_ir::NotifConstValue::Int(0), + }] + ); + // `locked` renames too, and stamps a boolean constant. + let locked = of("locked"); + assert_eq!(locked[0].action_type.as_deref(), Some("restrict")); + assert_eq!( + locked[0].constant_fields[0].value, + wa_ir::NotifConstValue::Bool(true) + ); +} + +#[test] +fn group_action_arms_recover_fields_children_and_branches() { + let ir = extract_notif(GROUP_ACTIONS_BUNDLE, "2.3000.test"); + let actions = group_actions(&ir); + let one = |tag: &str| { + actions + .iter() + .find(|a| a.wire_tag == tag) + .unwrap_or_else(|| panic!("no arm for {tag}")) + }; + // A presence-guarded attr is optional; an unguarded one is required. + let add = one("add"); + let reason = add + .fields + .iter() + .find(|f| f.name == "reason") + .expect("reason"); + assert!(!reason.required, "hasAttr(…) ? … : null → optional"); + // The participant list lives behind a module-local helper; it must still be + // recovered, with the per-participant fields. + let participants = add + .children + .iter() + .find(|c| c.name == "participants") + .expect("participants child"); + assert_eq!(participants.wire_tag, "participant"); + let names: Vec<&str> = participants + .fields + .iter() + .map(|f| f.name.as_str()) + .collect(); + assert_eq!(names, ["id", "displayName", "kind"]); + assert_eq!( + participants.fields[0].field_type, + wa_ir::ParsedFieldType::UserJid + ); + // An inline (non-helper) mapped child works the same way. + assert_eq!(one("revoke").children[0].wire_tag, "participant"); + // An arm that branches into two DIFFERENT actions yields two arms of the union, + // sharing the wire tag — not one arm with the first branch's shape. + let desc: Vec<_> = actions + .iter() + .filter(|a| a.wire_tag == "description") + .collect(); + let types: Vec<&str> = desc + .iter() + .filter_map(|a| a.action_type.as_deref()) + .collect(); + assert_eq!(types, ["desc_remove", "desc_add"]); + // The `` content read is flagged as content, with the tag as its wire name. + let body = desc[1] + .fields + .iter() + .find(|f| f.name == "desc") + .expect("desc"); + assert!(body.content); + assert_eq!(body.wire_name, "body"); +} + +#[test] +fn handler_without_a_const_keyed_switch_has_no_actions() { + // Most handlers forward straight to a `WADeprecatedWapParser` and carry no action + // union; they must not sprout a phantom one. The fixture dispatches `devices` + // alongside `w:gp2` precisely so this assertion actually runs — with only `w:gp2` in + // the bundle the loop body would never execute and the property would go untested. + let ir = extract_notif(GROUP_ACTIONS_BUNDLE, "2.3000.test"); + let others: Vec<&str> = ir + .notifications + .iter() + .filter(|n| n.notif_type != "w:gp2") + .map(|n| n.notif_type.as_str()) + .collect(); + assert!( + others.contains(&"devices"), + "fixture must dispatch a second, action-less type or this test is vacuous" + ); + for n in &ir.notifications { + if n.notif_type != "w:gp2" { + assert!(n.actions.is_empty(), "{} grew actions", n.notif_type); + } + } +} + +#[test] +fn a_null_coalesced_field_keeps_its_wire_source() { + // The minifier hides the accessor in the ternary's TEST: + // `(n = child.maybeAttrString("threshold")) != null ? n : void 0`. Following the + // consequent alone finds a bare `n` that nothing binds, and the field vanishes — + // which is exactly how `locked`'s `threshold` was being lost. + let ir = extract_notif(GROUP_ACTIONS_BUNDLE, "2.3000.test"); + let locked = notif(&ir, "w:gp2") + .actions + .iter() + .find(|a| a.wire_tag == "locked") + .expect("locked arm"); + let threshold = locked + .fields + .iter() + .find(|f| f.name == "threshold") + .expect("threshold field"); + assert_eq!(threshold.wire_name, "threshold"); + assert!(!threshold.required, "read behind a null-coalesce guard"); +} + +#[test] +fn a_helper_returning_several_actions_yields_several_arms() { + // `case UNLINK: return I(child)` delegates wholesale to a helper that branches into + // DIFFERENT actions. Folding them into one definition keeps whichever `actionType` + // resolved first and silently drops the rest, so the branches must surface as + // sibling arms of the union — the same treatment an inline ternary gets. + let ir = extract_notif(GROUP_ACTIONS_BUNDLE, "2.3000.test"); + let unlink: Vec<&str> = notif(&ir, "w:gp2") + .actions + .iter() + .filter(|a| a.wire_tag == "unlink") + .filter_map(|a| a.action_type.as_deref()) + .collect(); + assert_eq!(unlink, ["desc_remove", "desc_add"]); +} + +#[test] +fn a_branch_local_binding_is_in_scope_for_its_return() { + // `var` is function-scoped, so a declaration inside an `if` block is in scope for the + // return inside it. Now that returns are collected from nested branches, their locals + // have to be too — otherwise `if (c) { var sid = child.attrString("id"); return + // {descId: sid} }` yields a return whose `sid` resolves to nothing and is dropped. + let ir = extract_notif(GROUP_ACTIONS_BUNDLE, "2.3000.test"); + let arm = notif(&ir, "w:gp2") + .actions + .iter() + .find(|a| a.wire_tag == "subject" && a.action_type.as_deref() == Some("desc_remove")) + .expect("the branch arm"); + let f = arm + .fields + .iter() + .find(|f| f.name == "descId") + .expect("descId"); + assert_eq!(f.wire_name, "id"); +} + +#[test] +fn an_expression_bodied_arrow_callback_yields_its_field() { + // `p => wid(p.maybeAttrPhoneUserJid("phone_number"))` has no `return`: oxc stores the + // body as a lone expression, so a return-only scan reported the repeated child with an + // empty field list. The accessor also has to be typed as the PN user JID it is, not as + // a bare string. + let ir = extract_notif(GROUP_ACTIONS_BUNDLE, "2.3000.test"); + let owners = notif(&ir, "w:gp2") + .actions + .iter() + .find(|a| a.wire_tag == "revoke") + .expect("revoke arm") + .children + .iter() + .find(|c| c.name == "owners") + .expect("owners child"); + assert_eq!(owners.wire_tag, "owner"); + let f = owners.fields.first().expect("a field from the arrow body"); + assert_eq!(f.wire_name, "phone_number"); + assert_eq!(f.field_type, wa_ir::ParsedFieldType::UserJid); + assert!(!f.required, "maybeAttr* is optional"); +} + +#[test] +fn sibling_branches_rebinding_a_name_each_keep_their_own_accessor() { + // The minifier reuses short names across mutually exclusive branches. A single + // flattened scope would make one branch's return read the OTHER branch's attribute — + // a wrong `wireName`, not a missing field, which is the failure mode this module + // refuses everywhere else. Each return therefore resolves in its own scope. + let ir = extract_notif(GROUP_ACTIONS_BUNDLE, "2.3000.test"); + let arms: Vec<_> = notif(&ir, "w:gp2") + .actions + .iter() + .filter(|a| a.wire_tag == "subject") + .collect(); + let wire = |action: &str, field: &str| { + arms.iter() + .find(|a| a.action_type.as_deref() == Some(action)) + .and_then(|a| a.fields.iter().find(|f| f.name == field)) + .map(|f| f.wire_name.as_str()) + }; + // Both branches bind `n`, to different attributes. + assert_eq!(wire("desc_remove", "descId"), Some("id")); + assert_eq!(wire("subject", "subject"), Some("subject")); +} + +#[test] +fn a_logical_and_guard_reads_its_value_operand() { + // `child.hasAttr("note") && child.attrString("note")` carries the value on the RIGHT. + // Taking the left yields `hasAttr`, which is deliberately not a wire accessor, so the + // field disappeared. + let ir = extract_notif(GROUP_ACTIONS_BUNDLE, "2.3000.test"); + let note = notif(&ir, "w:gp2") + .actions + .iter() + .filter(|a| a.wire_tag == "subject") + .find_map(|a| a.fields.iter().find(|f| f.name == "note")) + .expect("note field"); + assert_eq!(note.wire_name, "note"); +} + +#[test] +fn an_action_enum_field_carries_its_variants() { + // `maybeAttrEnum("type", o("Mod").GROUP_PARTICIPANT_TYPES)` — a bare `"type": "enum"` + // says the value is constrained but not to what, leaving an emitter to guess. + let ir = extract_notif(GROUP_ACTIONS_BUNDLE, "2.3000.test"); + let kind = notif(&ir, "w:gp2") + .actions + .iter() + .find(|a| a.wire_tag == "add") + .expect("add arm") + .children + .iter() + .find(|c| c.name == "participants") + .expect("participants") + .fields + .iter() + .find(|f| f.name == "kind") + .expect("kind field"); + // The accessor is an enum accessor, so the field is typed as one — the `enumRef` + // hangs off a field a consumer filtering on `type == "enum"` will actually reach. + assert_eq!(kind.field_type, wa_ir::ParsedFieldType::Enum); + let er = kind.enum_ref.as_ref().expect("resolved enum"); + assert_eq!(er.name, "GROUP_PARTICIPANT_TYPES"); + let values: Vec<&str> = er.variants.iter().map(|v| v.value.as_str()).collect(); + assert_eq!(values, ["admin", "superadmin", "participant"]); +} + +#[test] +fn a_value_position_helper_weakens_its_branch_only_fields() { + // A helper used as an `extends` operand can return mutually exclusive shapes. + // Accumulating them makes the enclosing action require BOTH and reject either legal + // payload, so the branches are merged with the same optionality rule the switch arms + // use: a field only some branches carry is optional. + let ir = extract_notif(GROUP_ACTIONS_BUNDLE, "2.3000.test"); + let eph = notif(&ir, "w:gp2") + .actions + .iter() + .find(|a| a.wire_tag == "ephemeral") + .expect("ephemeral arm"); + let f = |name: &str| eph.fields.iter().find(|f| f.name == name); + for name in ["alpha", "beta"] { + let field = f(name).unwrap_or_else(|| panic!("{name} recovered")); + assert!(!field.required, "{name} comes from only one branch"); + } + // The arm's own unconditional read stays required. + assert!(f("duration").expect("duration").required); +} + +#[test] +fn a_defaulted_read_stays_required() { + // `child.attrString("code") || "none"` still calls `attrString`, which rejects an + // absent attribute — the right operand only defaults a value the parser already + // demanded. Classifying every logical expression as a presence guard marked it + // optional. + let ir = extract_notif(GROUP_ACTIONS_BUNDLE, "2.3000.test"); + let code = notif(&ir, "w:gp2") + .actions + .iter() + .find(|a| a.wire_tag == "ephemeral") + .expect("ephemeral arm") + .fields + .iter() + .find(|f| f.name == "code") + .expect("code field"); + assert_eq!(code.wire_name, "code"); + assert!(code.required, "`a || default` is not a presence guard"); +} + +#[test] +fn a_const_table_on_a_non_export_receiver_is_ignored() { + // `cache.GROUP_NOTIFICATION_TAG = {…}` written before the real + // `exports.GROUP_NOTIFICATION_TAG = …` would otherwise be taken as the export and, + // being first, kept — resolving case labels through an unrelated table and minting + // wrong wire tags. Only the module factory's own parameters count as receivers. + let ir = extract_notif(GROUP_ACTIONS_BUNDLE, "2.3000.test"); + let tags: Vec<&str> = notif(&ir, "w:gp2") + .actions + .iter() + .map(|a| a.wire_tag.as_str()) + .collect(); + assert!(tags.contains(&"add"), "the real table must win: {tags:?}"); + assert!( + !tags.iter().any(|t| t.starts_with("WRONG_")), + "decoy table leaked into the catalog: {tags:?}" + ); +} + +#[test] +fn a_branching_mapped_child_callback_weakens_its_branch_only_fields() { + // A callback returning different objects from an `if` describes alternative element + // shapes. Flattening every property in the body into one list marks a field read in + // only one branch as required, so a consumer would reject a legal element. + let ir = extract_notif(GROUP_ACTIONS_BUNDLE, "2.3000.test"); + let entries = notif(&ir, "w:gp2") + .actions + .iter() + .find(|a| a.wire_tag == "modify") + .expect("modify arm") + .children + .iter() + .find(|c| c.name == "entries") + .expect("entries child"); + let f = |name: &str| entries.fields.iter().find(|f| f.name == name); + assert!(f("id").expect("id").required, "read by every branch"); + assert!(!f("extra").expect("extra").required, "read by one branch"); +} + +#[test] +fn a_return_sees_only_the_bindings_that_ran_before_it() { + // `var z = attr("first"); if (c) return {pick:z}; var z = attr("second"); return + // {pick:z}` — hoisting moves the declaration, not the assignment, so the early return + // reads `first`. A scope built as a pre-pass over the whole statement list installs + // the later initializer first and reports both returns as reading `second`. + let ir = extract_notif(GROUP_ACTIONS_BUNDLE, "2.3000.test"); + let pick = |action: &str| { + notif(&ir, "w:gp2") + .actions + .iter() + .filter(|a| a.wire_tag == "modify") + .find(|a| a.action_type.as_deref() == Some(action)) + .and_then(|a| a.fields.iter().find(|f| f.name == "pick")) + .map(|f| f.wire_name.as_str()) + }; + assert_eq!( + pick("modify"), + Some("first"), + "the early return ran before the rebind" + ); + assert_eq!(pick("restrict"), Some("second")); +} + +#[test] +fn a_key_bound_to_different_wire_reads_is_dropped_not_guessed() { + // Two branches binding `who` to different attributes (`jid` and `lid`) have no single + // answer — publishing the first branch'"'"'s attribute would describe the other branch'"'"'s + // payload wrongly, and this is the JID conflation the repo treats as + // protocol-safety-critical. The key is dropped instead. + let ir = extract_notif(GROUP_ACTIONS_BUNDLE, "2.3000.test"); + let entries = notif(&ir, "w:gp2") + .actions + .iter() + .find(|a| a.wire_tag == "modify") + .expect("modify arm") + .children + .iter() + .find(|c| c.name == "entries") + .expect("entries child"); + let names: Vec<&str> = entries.fields.iter().map(|f| f.name.as_str()).collect(); + assert!( + !names.contains(&"who"), + "a conflicting source must be refused, not resolved to the first branch: {names:?}" + ); + // The unambiguous keys still merge normally. + let f = |n: &str| entries.fields.iter().find(|f| f.name == n); + assert!(f("id").expect("id").required, "read by every branch"); + assert!(!f("extra").expect("extra").required, "read by one branch"); +} + +#[test] +fn a_fall_through_label_with_setup_still_inherits_the_shared_action() { + // `case GROWTH_LOCKED: log(); case SUSPENDED: return {…}` — the first label has a + // non-empty body that produces no shape and falls through. Treating "non-empty" as + // "its own arm" lost the action type and every field of a legally dispatched tag. + let ir = extract_notif(GROUP_ACTIONS_BUNDLE, "2.3000.test"); + let arm = notif(&ir, "w:gp2") + .actions + .iter() + .find(|a| a.wire_tag == "growth_locked") + .expect("growth_locked arm"); + assert_eq!( + arm.action_type.as_deref(), + Some("restrict"), + "must inherit the body it falls through into" + ); + assert!(!arm.constant_fields.is_empty(), "including its constants"); +} + +#[test] +fn a_third_branch_cannot_resurrect_a_conflicted_key() { + // A(jid) vs B(lid) tombstones `who`; without a tombstone that outlives the single + // merge, C(jid) sees nothing there and adds it back — and the union again advertises + // one source while another legal branch reads a different attribute. + let ir = extract_notif(GROUP_ACTIONS_BUNDLE, "2.3000.test"); + let entries = notif(&ir, "w:gp2") + .actions + .iter() + .find(|a| a.wire_tag == "modify") + .expect("modify arm") + .children + .iter() + .find(|c| c.name == "entries") + .expect("entries child"); + let names: Vec<&str> = entries.fields.iter().map(|f| f.name.as_str()).collect(); + assert!( + !names.contains(&"who"), + "the third branch must not resurrect the conflict: {names:?}" + ); + assert!(names.contains(&"id"), "unambiguous keys survive: {names:?}"); +} + +#[test] +fn a_terminating_case_does_not_borrow_the_next_action() { + // `case INVITE: log(); break;` does not fall through. Scanning past the `break` for + // "the next case that yields a shape" would publish that action under `invite`, a + // shape the tag never produces. + let ir = extract_notif(GROUP_ACTIONS_BUNDLE, "2.3000.test"); + let invite: Vec<_> = notif(&ir, "w:gp2") + .actions + .iter() + .filter(|a| a.wire_tag == "invite") + .collect(); + assert_eq!(invite.len(), 1); + assert_eq!( + invite[0].action_type, None, + "a terminating arm produces no shape of its own, and must borrow none" + ); + assert!(invite[0].fields.is_empty() && invite[0].children.is_empty()); +} + +#[test] +fn an_arm_selecting_through_a_nested_switch_yields_both_actions() { + // `case UNLINK: switch (linkType) { case "parent": return {…}; default: return {…} }` + // describes two legal actions for one wire tag. Skipping nested switches — which the + // walk used to do, on the theory that they are a different dispatch level — left the + // arm empty. + let ir = extract_notif(GROUP_ACTIONS_BUNDLE, "2.3000.test"); + let mut got: Vec<&str> = notif(&ir, "w:gp2") + .actions + .iter() + .filter(|a| a.wire_tag == "link") + .filter_map(|a| a.action_type.as_deref()) + .collect(); + got.sort_unstable(); + assert_eq!(got, ["desc_add", "desc_remove"]); +} + +#[test] +fn a_child_field_conflict_survives_a_third_branch() { + // The alternative rule lives in ONE place now, so a conflict inside a MAPPED CHILD + // gets the same tombstone the top-level scalars do. Before, the child merge created a + // fresh conflict set per call — the same defect as the outer level, one layer down — + // so `A(p)` vs `B(q)` removed `v` and `C(p)` put it back. + let ir = extract_notif(GROUP_ACTIONS_BUNDLE, "2.3000.test"); + let rows = notif(&ir, "w:gp2") + .actions + .iter() + .find(|a| a.wire_tag == "announcement") + .expect("announcement arm") + .children + .iter() + .find(|c| c.name == "rows") + .expect("rows child"); + let names: Vec<&str> = rows.fields.iter().map(|f| f.name.as_str()).collect(); + assert!( + !names.contains(&"v"), + "a child field two branches disagree on must stay refused: {names:?}" + ); +} + +#[test] +fn a_fall_through_label_contributes_its_own_bindings() { + // `case A: var thr = child.attrString("threshold"); case B: return {…, seeded: thr}` + // — the A path binds before falling through, so handing the shape only B's body + // dropped the field. The chain now carries every statement it executes. + let ir = extract_notif(GROUP_ACTIONS_BUNDLE, "2.3000.test"); + let seeded = notif(&ir, "w:gp2") + .actions + .iter() + .find(|a| a.wire_tag == "growth_locked") + .expect("growth_locked arm") + .fields + .iter() + .find(|f| f.name == "seeded") + .expect("the binding from the fall-through label"); + assert_eq!(seeded.wire_name, "threshold"); +} + +/// A second `w:gp2` handler covering the shapes the real bundle does not exercise today. +/// +/// Every behaviour below is **latent** against the pinned bundle — the constructs are +/// legal, WA writes some of them elsewhere, and the extractor got them wrong — so a +/// fixture is the only thing that can hold the fix in place. Without it a later +/// refactor would silently restore the old answer and `generated/` would not move. +const GROUP_ACTIONS_EDGE_BUNDLE: &str = r#" +__d("WAWebCommsHandleLoggedInStanza",["WAWebHandleGroupNotification"],function(g,r,d,o,e,i,l){ + l.handle = function(){ return (function*(e,t){ + var n = e.attrs; + switch (e.tag) { + case "notification": + switch (n.type) { + case "w:gp2": return yield r("WAWebHandleGroupNotification")(e); + } + } + }); }; +}, 1); +__d("WAWebHandleGroupNotificationConst",[],(function(t,n,r,o,a,i,l){ + l.GROUP_NOTIFICATION_TAG=Object.freeze({EVICT:"evict",COND:"cond",REBIND:"rebind",PICK:"pick",BARE:"bare",HELPER:"helper",ESCAPE:"escape",TAIL:"tail",JOIN:"join",SEQ:"seq",SUFFIX:"suffix",AFTER:"after",TRY:"try_tag",FIN:"fin",FINCOND:"fincond",FINTHROW:"finthrow",MULTI:"multi",MULTI3:"multi3",DEAD:"dead",LIT:"lit",LOOP:"loop_tag",FINTRY:"fintry",PARAM:"param",BLK:"blk",EXH:"exh",NFT:"nft",LATE:"late",DOW:"dow",SHADOW:"shadow",CATCHP:"catchp",DOWX:"dowx",SAME:"same",NEST:"nest",DOWB:"dowb",PVAL:"pval",SPREAD:"spread",DOWBRK:"dowbrk",FINW:"finw",FORI:"fori",CONDW:"condw",SPRD:"sprd"}); +}), 1); +__d("WAWebGroupType",[],(function(t,n,r,o,a,i,l){ + l.GROUP_ACTIONS=Object.freeze({FIRST:"first",SECOND:"second",THIRD:"third"}); +}), 1); +__d("WAWebHandleGroupNotification",["WAWebHandleGroupNotificationConst","WAWebGroupType"],(function(t,n,r,o,a,i,l){ + function hlp(e){ return {actionType:o("WAWebGroupType").GROUP_ACTIONS.SECOND, extra:e.attrString("extra")}; } + function norm(v){ return v == null ? null : v; } + function mk(v){ return {actionType:o("WAWebGroupType").GROUP_ACTIONS.THIRD, id:v}; } + function h(e){ + var x=e.mapChildrenWithTag("child", function(t){ + switch (t.tag) { + case o("WAWebHandleGroupNotificationConst").GROUP_NOTIFICATION_TAG.EVICT: + return babelHelpers.extends({actionType:o("WAWebGroupType").GROUP_ACTIONS.FIRST, id:t.attrString("jid")}, {id:0}); + case o("WAWebHandleGroupNotificationConst").GROUP_NOTIFICATION_TAG.COND: + if (t.hasChild("early")) return {actionType:o("WAWebGroupType").GROUP_ACTIONS.FIRST, a:t.attrString("a")}; + case o("WAWebHandleGroupNotificationConst").GROUP_NOTIFICATION_TAG.PICK: + return {actionType:o("WAWebGroupType").GROUP_ACTIONS.SECOND, b:t.attrString("b")}; + case o("WAWebHandleGroupNotificationConst").GROUP_NOTIFICATION_TAG.REBIND: { + var v=t.attrString("jid"); + v=t.attrString("lid"); + return {actionType:o("WAWebGroupType").GROUP_ACTIONS.THIRD, id:v}; + } + case o("WAWebHandleGroupNotificationConst").GROUP_NOTIFICATION_TAG.BARE: + return {actionType:o("WAWebGroupType").GROUP_ACTIONS.THIRD, who:t.mapChildrenWithTag("p", function(p){ return p.hasChild("z") ? p.attrString("jid") : p.attrString("lid"); })}; + case o("WAWebHandleGroupNotificationConst").GROUP_NOTIFICATION_TAG.HELPER: + return babelHelpers.extends({actionType:o("WAWebGroupType").GROUP_ACTIONS.FIRST}, hlp(t)); + case o("WAWebHandleGroupNotificationConst").GROUP_NOTIFICATION_TAG.ESCAPE: + switch (t.attrString("k")) { + case "a": if (t.hasChild("q")) break; return {actionType:o("WAWebGroupType").GROUP_ACTIONS.FIRST, e1:t.attrString("e1")}; + default: return {actionType:o("WAWebGroupType").GROUP_ACTIONS.SECOND, e2:t.attrString("e2")}; + } + case o("WAWebHandleGroupNotificationConst").GROUP_NOTIFICATION_TAG.TAIL: + return {actionType:o("WAWebGroupType").GROUP_ACTIONS.THIRD, t1:t.attrString("t1")}; + case o("WAWebHandleGroupNotificationConst").GROUP_NOTIFICATION_TAG.JOIN: { + var j=t.attrString("jid"); + if (t.hasChild("alt")) j=t.attrString("lid"); + return {actionType:o("WAWebGroupType").GROUP_ACTIONS.FIRST, id:j}; + } + case o("WAWebHandleGroupNotificationConst").GROUP_NOTIFICATION_TAG.TRY: + try { return {actionType:o("WAWebGroupType").GROUP_ACTIONS.FIRST, ok:t.attrString("ok")}; } + catch (e) { return {actionType:o("WAWebGroupType").GROUP_ACTIONS.SECOND, err:t.attrString("err")}; } + case o("WAWebHandleGroupNotificationConst").GROUP_NOTIFICATION_TAG.FIN: + try { return {actionType:o("WAWebGroupType").GROUP_ACTIONS.FIRST, a:t.attrString("a")}; } + finally { return {actionType:o("WAWebGroupType").GROUP_ACTIONS.THIRD, f:t.attrString("f")}; } + case o("WAWebHandleGroupNotificationConst").GROUP_NOTIFICATION_TAG.FINCOND: + try { return {actionType:o("WAWebGroupType").GROUP_ACTIONS.FIRST, a:t.attrString("a")}; } + finally { if (t.hasChild("z")) return {actionType:o("WAWebGroupType").GROUP_ACTIONS.SECOND, b:t.attrString("b")}; } + case o("WAWebHandleGroupNotificationConst").GROUP_NOTIFICATION_TAG.FINTHROW: + try { return {actionType:o("WAWebGroupType").GROUP_ACTIONS.FIRST, a:t.attrString("a")}; } + finally { throw new Error("x"); } + case o("WAWebHandleGroupNotificationConst").GROUP_NOTIFICATION_TAG.MULTI: + return {actionType:o("WAWebGroupType").GROUP_ACTIONS.SECOND, id:combine(t.attrString("jid"), t.attrString("lid")), plain:t.attrString("plain")}; + case o("WAWebHandleGroupNotificationConst").GROUP_NOTIFICATION_TAG.MULTI3: + return {actionType:o("WAWebGroupType").GROUP_ACTIONS.FIRST, id:combine(t.attrString("jid"), t.attrString("jid"), t.attrString("lid")), plain:t.attrString("plain")}; + case o("WAWebHandleGroupNotificationConst").GROUP_NOTIFICATION_TAG.DEAD: + return {actionType:o("WAWebGroupType").GROUP_ACTIONS.FIRST, a:t.attrString("a")}; + return {actionType:o("WAWebGroupType").GROUP_ACTIONS.SECOND, b:t.attrString("b")}; + case o("WAWebHandleGroupNotificationConst").GROUP_NOTIFICATION_TAG.LIT: + return {actionType:"create", who:t.attrString("who")}; + case o("WAWebHandleGroupNotificationConst").GROUP_NOTIFICATION_TAG.LOOP: + while (t.hasChild("more")) { return {actionType:o("WAWebGroupType").GROUP_ACTIONS.FIRST, l:t.attrString("l")}; } + return {actionType:o("WAWebGroupType").GROUP_ACTIONS.SECOND, m:t.attrString("m")}; + case o("WAWebHandleGroupNotificationConst").GROUP_NOTIFICATION_TAG.FINTRY: { + var fx = t.attrString("jid"); + try { fx = t.attrString("lid"); } finally { return {actionType:o("WAWebGroupType").GROUP_ACTIONS.THIRD, id:fx}; } + } + case o("WAWebHandleGroupNotificationConst").GROUP_NOTIFICATION_TAG.PARAM: + return {actionType:o("WAWebGroupType").GROUP_ACTIONS.FIRST, reason:t.hasAttr("reason")?norm(t.attrString("reason")):null}; + case o("WAWebHandleGroupNotificationConst").GROUP_NOTIFICATION_TAG.BLK: { + var bx = t.attrString("jid"); + { bx = t.attrString("lid"); } + return {actionType:o("WAWebGroupType").GROUP_ACTIONS.FIRST, id:bx}; + } + case o("WAWebHandleGroupNotificationConst").GROUP_NOTIFICATION_TAG.EXH: + if (t.hasChild("q")) return {actionType:o("WAWebGroupType").GROUP_ACTIONS.FIRST, a:t.attrString("a")}; + else return {actionType:o("WAWebGroupType").GROUP_ACTIONS.SECOND, b:t.attrString("b")}; + return {actionType:o("WAWebGroupType").GROUP_ACTIONS.THIRD, c:t.attrString("c")}; + case o("WAWebHandleGroupNotificationConst").GROUP_NOTIFICATION_TAG.NFT: { + var nx; + switch (t.attrString("k")) { + case "a": nx = t.attrString("jid"); + default: return {actionType:o("WAWebGroupType").GROUP_ACTIONS.FIRST, id:nx}; + } + } + case o("WAWebHandleGroupNotificationConst").GROUP_NOTIFICATION_TAG.LATE: { + var lr; + lr = {actionType:o("WAWebGroupType").GROUP_ACTIONS.FIRST, id:t.attrString("jid")}; + return lr; + } + case o("WAWebHandleGroupNotificationConst").GROUP_NOTIFICATION_TAG.DOW: { + var dw; + do { dw = t.attrString("lid"); } while (t.hasChild("again")); + return {actionType:o("WAWebGroupType").GROUP_ACTIONS.SECOND, id:dw}; + } + case o("WAWebHandleGroupNotificationConst").GROUP_NOTIFICATION_TAG.SHADOW: { + var sh = t.attrString("jid"); + { let sh = t.attrString("lid"); } + return {actionType:o("WAWebGroupType").GROUP_ACTIONS.THIRD, id:sh}; + } + case o("WAWebHandleGroupNotificationConst").GROUP_NOTIFICATION_TAG.CATCHP: { + var e2 = t.attrString("jid"); + try { return {actionType:o("WAWebGroupType").GROUP_ACTIONS.FIRST, id:e2}; } + catch (e2) { return {actionType:o("WAWebGroupType").GROUP_ACTIONS.SECOND, id:e2}; } + } + case o("WAWebHandleGroupNotificationConst").GROUP_NOTIFICATION_TAG.DOWX: + do { return {actionType:o("WAWebGroupType").GROUP_ACTIONS.FIRST, a:t.attrString("a")}; } while (t.hasChild("again")); + return {actionType:o("WAWebGroupType").GROUP_ACTIONS.SECOND, b:t.attrString("b")}; + case o("WAWebHandleGroupNotificationConst").GROUP_NOTIFICATION_TAG.SAME: + return {actionType:o("WAWebGroupType").GROUP_ACTIONS.FIRST, id:t.hasChild("q") ? t.attrString("jid") : t.attrString("jid")}; + case o("WAWebHandleGroupNotificationConst").GROUP_NOTIFICATION_TAG.NEST: + return {actionType:o("WAWebGroupType").GROUP_ACTIONS.SECOND, who:t.mapChildrenWithTag("p", function(p){ return {meta:{id:p.attrString("id")}, top:p.attrString("top")}; })}; + case o("WAWebHandleGroupNotificationConst").GROUP_NOTIFICATION_TAG.DOWB: { + var db; + do { if (t.hasChild("skip")) break; db = t.attrString("lid"); } while (t.hasChild("again")); + return {actionType:o("WAWebGroupType").GROUP_ACTIONS.FIRST, id:db}; + } + case o("WAWebHandleGroupNotificationConst").GROUP_NOTIFICATION_TAG.PVAL: + return mk(t.attrString("jid")); + case o("WAWebHandleGroupNotificationConst").GROUP_NOTIFICATION_TAG.DOWBRK: + do { break; } while (t.hasChild("x")); + return {actionType:o("WAWebGroupType").GROUP_ACTIONS.SECOND, b:t.attrString("b")}; + case o("WAWebHandleGroupNotificationConst").GROUP_NOTIFICATION_TAG.FINW: { + var fw; + try { fw = t.attrString("jid"); } finally { fw = t.attrString("lid"); } + return {actionType:o("WAWebGroupType").GROUP_ACTIONS.FIRST, id:fw}; + } + case o("WAWebHandleGroupNotificationConst").GROUP_NOTIFICATION_TAG.FORI: { + var fi = t.attrString("jid"); + for (fi = t.attrString("lid"); t.hasChild("y"); ) return {actionType:o("WAWebGroupType").GROUP_ACTIONS.SECOND, id:fi}; + return {actionType:o("WAWebGroupType").GROUP_ACTIONS.THIRD, z:t.attrString("z")}; + } + case o("WAWebHandleGroupNotificationConst").GROUP_NOTIFICATION_TAG.CONDW: { + var cw = t.attrString("jid"); + t.hasChild("c") && (cw = t.attrString("lid")); + return {actionType:o("WAWebGroupType").GROUP_ACTIONS.FIRST, id:cw}; + } + case o("WAWebHandleGroupNotificationConst").GROUP_NOTIFICATION_TAG.SPRD: + return babelHelpers.extends({actionType:o("WAWebGroupType").GROUP_ACTIONS.FIRST}, {id:t.attrString("jid"), ...base}); + case o("WAWebHandleGroupNotificationConst").GROUP_NOTIFICATION_TAG.SUFFIX: + switch (t.attrString("k")) { + case "a": t.attrString("setup"); + default: return {actionType:o("WAWebGroupType").GROUP_ACTIONS.FIRST, s:t.attrString("s")}; + } + case o("WAWebHandleGroupNotificationConst").GROUP_NOTIFICATION_TAG.AFTER: + return {actionType:o("WAWebGroupType").GROUP_ACTIONS.THIRD, a1:t.attrString("a1")}; + case o("WAWebHandleGroupNotificationConst").GROUP_NOTIFICATION_TAG.SEQ: { + var s1, s2; + s1=t.attrString("jid"), s2=t.attrInt("n"); + return {actionType:o("WAWebGroupType").GROUP_ACTIONS.SECOND, id:s1, n:s2}; + } + } + }); + return {actions:x}; + } + l.handleGroupNotification=h; +}), 1); +"#; + +/// The single action arm for `tag` in the edge-case bundle. +fn edge_action<'a>(ir: &'a wa_ir::NotifIr, tag: &str) -> &'a wa_ir::NotifActionDef { + let mut found = notif(ir, "w:gp2") + .actions + .iter() + .filter(|a| a.wire_tag == tag); + let a = found + .next() + .unwrap_or_else(|| panic!("no action arm for wire tag {tag:?}")); + assert!(found.next().is_none(), "expected one arm for {tag:?}"); + a +} + +#[test] +fn a_later_write_evicts_the_key_from_every_collection() { + // `extends({id: attrString("jid")}, {id: 0})` yields only `id: 0` at runtime. + // Replacing within each collection separately published BOTH a wire-read field and a + // constant named `id` — a shape no execution produces. + let ir = extract_notif(GROUP_ACTIONS_EDGE_BUNDLE, "2.3000.test"); + let a = edge_action(&ir, "evict"); + assert!( + !a.fields.iter().any(|f| f.name == "id"), + "the constant must evict the earlier wire read: {:?}", + a.fields + ); + assert_eq!( + a.constant_fields.iter().filter(|c| c.name == "id").count(), + 1, + "exactly one `id`, and it is the constant" + ); +} + +#[test] +fn a_conditionally_returning_case_still_falls_through() { + // `case COND: if (cond) return FIRST; case PICK: return SECOND;` — tag `cond` can + // legally produce either. Stopping at the first shape published only FIRST. + let ir = extract_notif(GROUP_ACTIONS_EDGE_BUNDLE, "2.3000.test"); + let cond: Vec<&str> = notif(&ir, "w:gp2") + .actions + .iter() + .filter(|a| a.wire_tag == "cond") + .filter_map(|a| a.action_type.as_deref()) + .collect(); + assert!( + cond.contains(&"second"), + "the fall-through target must be reachable from `cond`: {cond:?}" + ); +} + +#[test] +fn a_reassignment_replaces_the_declared_binding() { + // `var v = attrString("jid"); v = attrString("lid"); return {id: v}` reads `lid`. + // Tracking declarations only left the initializer installed. + let ir = extract_notif(GROUP_ACTIONS_EDGE_BUNDLE, "2.3000.test"); + let a = edge_action(&ir, "rebind"); + let id = a + .fields + .iter() + .find(|f| f.name == "id") + .expect("the `id` field survives the reassignment"); + assert_eq!( + id.wire_name, "lid", + "the value at the return is the reassigned one" + ); +} + +#[test] +fn a_bare_callback_read_is_optional_when_only_one_branch_takes_it() { + // `p => cond ? p.attrString("jid") : p.attrString("lid")` reads exactly one per + // element. The bare-value fallback bypassed the branch fold and marked both required. + let ir = extract_notif(GROUP_ACTIONS_EDGE_BUNDLE, "2.3000.test"); + let a = edge_action(&ir, "bare"); + let child = a + .children + .iter() + .find(|c| c.name == "who") + .expect("the mapped child is recovered"); + // Asserted before the requiredness check: `all` on an empty list is vacuously true, + // and this is exactly the path that could regress to recovering no fields at all. + let names: Vec<&str> = child.fields.iter().map(|f| f.wire_name.as_str()).collect(); + assert!( + names.contains(&"jid") && names.contains(&"lid"), + "both alternative reads survive the fold: {names:?}" + ); + assert!( + child.fields.iter().all(|f| !f.required), + "a read taken on only one branch is not required: {:?}", + child.fields + ); +} + +#[test] +fn a_helper_operand_replaces_the_earlier_action_type() { + // `extends({actionType: FIRST}, hlp(t))` where the helper returns SECOND yields + // SECOND at runtime. Copying the helper's `actionType` only into an empty slot + // dispatched the shape as FIRST. + let ir = extract_notif(GROUP_ACTIONS_EDGE_BUNDLE, "2.3000.test"); + let a = edge_action(&ir, "helper"); + assert_eq!( + a.action_type.as_deref(), + Some("second"), + "the later operand wins, `actionType` included" + ); +} + +#[test] +fn a_nested_break_path_keeps_the_outer_fall_through() { + // `case "a": if (cond) break; return FIRST;` inside a nested switch: the `break` + // leaves only the INNER switch, so control resumes in the outer `escape` case and + // falls through to `tail`. Treating the later `return` as proof that every path + // exited hid that action. + let ir = extract_notif(GROUP_ACTIONS_EDGE_BUNDLE, "2.3000.test"); + let got: Vec<&str> = notif(&ir, "w:gp2") + .actions + .iter() + .filter(|a| a.wire_tag == "escape") + .filter_map(|a| a.action_type.as_deref()) + .collect(); + assert!( + got.contains(&"third"), + "the break path falls through to the next outer case: {got:?}" + ); +} + +#[test] +fn a_binding_reassigned_in_one_branch_is_not_reported_as_certain() { + // `var j = attrString("jid"); if (c) j = attrString("lid"); return {id: j}` reads + // `lid` on one legal path. Keeping the pre-branch binding published `jid` as fact. + let ir = extract_notif(GROUP_ACTIONS_EDGE_BUNDLE, "2.3000.test"); + let a = edge_action(&ir, "join"); + assert!( + !a.fields + .iter() + .any(|f| f.name == "id" && f.wire_name == "jid"), + "the branch write must not leave `jid` asserted: {:?}", + a.fields + ); +} + +#[test] +fn a_comma_sequence_of_assignments_binds_every_operand() { + // The minifier writes runs of assignments as one `SequenceExpression` + // (`s1 = t.attrString("jid"), s2 = t.attrInt("n")`); matching only a bare assignment + // statement skipped them all. + let ir = extract_notif(GROUP_ACTIONS_EDGE_BUNDLE, "2.3000.test"); + let a = edge_action(&ir, "seq"); + let wire = |name: &str| { + a.fields + .iter() + .find(|f| f.name == name) + .map(|f| f.wire_name.as_str()) + }; + assert_eq!(wire("id"), Some("jid")); + assert_eq!(wire("n"), Some("n")); +} + +#[test] +fn a_nested_case_exits_through_its_own_fall_through_suffix() { + // `case "a": setup(); default: return X` — the `a` path runs `setup()` and falls into + // the default's return, so the switch DOES leave the enclosing case on every path. + // Requiring each nested case body to exit on its own (accepting only an empty + // fall-through label) called it non-terminating, and `suffix` then borrowed the + // following outer case's action for a wire tag that never produces it. + let ir = extract_notif(GROUP_ACTIONS_EDGE_BUNDLE, "2.3000.test"); + let got: Vec<&str> = notif(&ir, "w:gp2") + .actions + .iter() + .filter(|a| a.wire_tag == "suffix") + .filter_map(|a| a.action_type.as_deref()) + .collect(); + assert!(got.contains(&"first"), "its own action survives: {got:?}"); + assert!( + !got.contains(&"third"), + "and it must not borrow the next case's: {got:?}" + ); +} + +#[test] +fn a_catch_block_return_is_a_legal_action() { + // WA wraps a parse in `try { … } catch (e) { … }` and the handler's return is as + // legal as the body's. Walking only the `try` body omitted the error path entirely. + let ir = extract_notif(GROUP_ACTIONS_EDGE_BUNDLE, "2.3000.test"); + let got: Vec<&str> = notif(&ir, "w:gp2") + .actions + .iter() + .filter(|a| a.wire_tag == "try_tag") + .filter_map(|a| a.action_type.as_deref()) + .collect(); + assert!(got.contains(&"first"), "the try body's action: {got:?}"); + assert!(got.contains(&"second"), "and the catch's: {got:?}"); +} + +#[test] +fn a_returning_finally_overrides_the_try_body() { + // A `finally` that returns discards whatever `try`/`catch` produced — it is the only + // shape the statement can yield, so reporting the body's would be a shape no + // execution reaches. + let ir = extract_notif(GROUP_ACTIONS_EDGE_BUNDLE, "2.3000.test"); + let got: Vec<&str> = notif(&ir, "w:gp2") + .actions + .iter() + .filter(|a| a.wire_tag == "fin") + .filter_map(|a| a.action_type.as_deref()) + .collect(); + assert_eq!(got, ["third"], "only the finalizer's shape: {got:?}"); +} + +#[test] +fn a_conditional_finally_leaves_the_try_result_legal() { + // `try { return A } finally { if (c) return B }` returns A when `c` is false. Deciding + // the override by "did the finalizer yield any shape" reported only B. + let ir = extract_notif(GROUP_ACTIONS_EDGE_BUNDLE, "2.3000.test"); + let mut got: Vec<&str> = notif(&ir, "w:gp2") + .actions + .iter() + .filter(|a| a.wire_tag == "fincond") + .filter_map(|a| a.action_type.as_deref()) + .collect(); + got.sort_unstable(); + assert_eq!(got, ["first", "second"], "both paths are legal: {got:?}"); +} + +#[test] +fn a_throwing_finally_yields_no_shape_at_all() { + // The mirror case: `finally { throw }` collects no returns, so emptiness read as + // "no override" and the try body's shape was published although it never escapes. + let ir = extract_notif(GROUP_ACTIONS_EDGE_BUNDLE, "2.3000.test"); + let got: Vec<&str> = notif(&ir, "w:gp2") + .actions + .iter() + .filter(|a| a.wire_tag == "finthrow") + .filter_map(|a| a.action_type.as_deref()) + .collect(); + assert!(got.is_empty(), "nothing is returned from this arm: {got:?}"); +} + +#[test] +fn a_wrapper_over_two_accessors_refuses_the_field() { + // `combine(t.attrString("jid"), t.attrString("lid"))` derives its value from both, and + // a field names ONE `wireName`. Taking the first stated as fact something the IR + // cannot express; the sibling read on the same arm must still survive. + let ir = extract_notif(GROUP_ACTIONS_EDGE_BUNDLE, "2.3000.test"); + let a = edge_action(&ir, "multi"); + assert!( + !a.fields.iter().any(|f| f.name == "id"), + "the ambiguous key is refused: {:?}", + a.fields + ); + assert!( + a.fields.iter().any(|f| f.name == "plain"), + "and the unambiguous sibling is kept: {:?}", + a.fields + ); +} + +#[test] +fn a_conflict_past_the_second_wrapper_argument_still_refuses() { + // `combine(a("jid"), a("jid"), a("lid"))` — the second read matches the first, so + // comparing only those two accepted `jid` and never looked at the conflicting third. + let ir = extract_notif(GROUP_ACTIONS_EDGE_BUNDLE, "2.3000.test"); + let a = edge_action(&ir, "multi3"); + assert!( + !a.fields.iter().any(|f| f.name == "id"), + "every argument is inspected: {:?}", + a.fields + ); + assert!( + a.fields.iter().any(|f| f.name == "plain"), + "and the unambiguous sibling survives: {:?}", + a.fields + ); +} + +#[test] +fn a_return_after_an_unconditional_return_is_unreachable() { + // `return A; return B;` — B never runs. Treating every syntactic return as reachable + // published it as a second legal action for the tag, and let statements below the + // return contribute fields too. + let ir = extract_notif(GROUP_ACTIONS_EDGE_BUNDLE, "2.3000.test"); + let got: Vec<&str> = notif(&ir, "w:gp2") + .actions + .iter() + .filter(|a| a.wire_tag == "dead") + .filter_map(|a| a.action_type.as_deref()) + .collect(); + assert_eq!(got, ["first"], "only the reachable shape: {got:?}"); +} + +#[test] +fn a_literal_action_type_is_kept() { + // `{actionType: "create"}` is fully static. Resolving only `o("Mod").OBJECT.MEMBER` + // left the arm with no `actionType`, indistinguishable from one the arm computes. + let ir = extract_notif(GROUP_ACTIONS_EDGE_BUNDLE, "2.3000.test"); + let a = edge_action(&ir, "lit"); + assert_eq!(a.action_type.as_deref(), Some("create")); +} + +#[test] +fn a_loop_body_return_is_collected() { + // `while (c) { return A } return B` legally produces both. Loops fell into the + // catch-all, so only B was emitted. + let ir = extract_notif(GROUP_ACTIONS_EDGE_BUNDLE, "2.3000.test"); + let mut got: Vec<&str> = notif(&ir, "w:gp2") + .actions + .iter() + .filter(|a| a.wire_tag == "loop_tag") + .filter_map(|a| a.action_type.as_deref()) + .collect(); + got.sort_unstable(); + assert_eq!(got, ["first", "second"], "both paths: {got:?}"); +} + +#[test] +fn a_finalizer_does_not_read_a_binding_the_try_overwrote() { + // `var x = a("jid"); try { x = a("lid") } finally { return {id: x} }` returns `lid`. + // Analyzing the finalizer against the pre-`try` scope published `jid` as fact; the + // body may also have thrown part-way, so neither source is certain and the name is + // tombstoned rather than guessed. + let ir = extract_notif(GROUP_ACTIONS_EDGE_BUNDLE, "2.3000.test"); + let a = edge_action(&ir, "fintry"); + assert!( + !a.fields.iter().any(|f| f.wire_name == "jid"), + "the stale pre-try source must not be published: {:?}", + a.fields + ); +} + +#[test] +fn a_helper_that_only_normalises_its_argument_keeps_the_wire_read() { + // `reason: hasAttr("reason") ? norm(t.attrString("reason")) : null` — `norm` is a + // module-local helper, so the inliner claimed the key, produced an empty shape + // (the helper reads no attribute of its own) and dropped the field. Live for + // `add`/`remove`/`delete`'s `reason` before the fallback to `read_field`. + let ir = extract_notif(GROUP_ACTIONS_EDGE_BUNDLE, "2.3000.test"); + let a = edge_action(&ir, "param"); + let f = a + .fields + .iter() + .find(|f| f.name == "reason") + .expect("the field survives the helper"); + assert_eq!(f.wire_name, "reason"); + assert!(!f.required, "it sits behind a presence guard"); +} + +#[test] +fn a_bare_block_hands_its_writes_back() { + // A bare block always runs and `var` is function-scoped, so + // `var x = a("jid"); { x = a("lid"); } return {id: x}` reads `lid`. Analyzing the + // block against a clone discarded the write and published the pre-block source. + let ir = extract_notif(GROUP_ACTIONS_EDGE_BUNDLE, "2.3000.test"); + let a = edge_action(&ir, "blk"); + let f = a + .fields + .iter() + .find(|f| f.name == "id") + .expect("the id field"); + assert_eq!( + f.wire_name, "lid", + "the block's write is what reaches the return" + ); +} + +#[test] +fn nothing_after_an_exhaustive_if_is_reachable() { + // `if (c) return A; else return B; return C;` — C never runs. The direct-return stop + // did not cover a statement that exits through both of its branches. + let ir = extract_notif(GROUP_ACTIONS_EDGE_BUNDLE, "2.3000.test"); + let mut got: Vec<&str> = notif(&ir, "w:gp2") + .actions + .iter() + .filter(|a| a.wire_tag == "exh") + .filter_map(|a| a.action_type.as_deref()) + .collect(); + got.sort_unstable(); + assert_eq!( + got, + ["first", "second"], + "the trailing return is dead: {got:?}" + ); +} + +#[test] +fn a_nested_case_carries_its_setup_to_the_case_it_falls_into() { + // `case "a": nx = t.attrString("jid"); default: return {id: nx}` — the `a` path runs + // the assignment and falls into the default's return. Analyzing each consequent + // against the same incoming scope lost `id` on that path. + let ir = extract_notif(GROUP_ACTIONS_EDGE_BUNDLE, "2.3000.test"); + let a = edge_action(&ir, "nft"); + assert!( + a.fields + .iter() + .any(|f| f.name == "id" && f.wire_name == "jid"), + "the fall-through setup reaches the return: {:?}", + a.fields + ); +} + +/// A handler whose payload union is SMALLER than an unrelated const-keyed switch beside +/// it. Picking by arm count would publish the wrong one. +const DECOY_SWITCH_BUNDLE: &str = r#" +__d("WAWebCommsHandleLoggedInStanza",["WAWebHandleGroupNotification"],function(g,r,d,o,e,i,l){ + l.handle = function(){ return (function*(e,t){ + var n = e.attrs; + switch (e.tag) { + case "notification": + switch (n.type) { + case "w:gp2": return yield r("WAWebHandleGroupNotification")(e); + } + } + }); }; +}, 1); +__d("WAWebHandleGroupNotificationConst",[],(function(t,n,r,o,a,i,l){ + l.GROUP_NOTIFICATION_TAG=Object.freeze({REAL:"real"}); + l.OTHER=Object.freeze({A:"a",B:"b",C:"c",D:"d"}); +}), 1); +__d("WAWebGroupType",[],(function(t,n,r,o,a,i,l){ + l.GROUP_ACTIONS=Object.freeze({FIRST:"first"}); +}), 1); +__d("WAWebHandleGroupNotification",["WAWebHandleGroupNotificationConst","WAWebGroupType"],(function(t,n,r,o,a,i,l){ + function h(e){ + var mode = e.attrString("mode"); + switch (mode) { + case o("WAWebHandleGroupNotificationConst").OTHER.A: return {actionType:o("WAWebGroupType").GROUP_ACTIONS.FIRST, x:e.attrString("x")}; + case o("WAWebHandleGroupNotificationConst").OTHER.B: return {actionType:o("WAWebGroupType").GROUP_ACTIONS.FIRST, y:e.attrString("y")}; + case o("WAWebHandleGroupNotificationConst").OTHER.C: return {actionType:o("WAWebGroupType").GROUP_ACTIONS.FIRST, z:e.attrString("z")}; + case o("WAWebHandleGroupNotificationConst").OTHER.D: return {actionType:o("WAWebGroupType").GROUP_ACTIONS.FIRST, w:e.attrString("w")}; + } + } + function top(e){ + var x=e.mapChildren(function(t){ + var tg = t.tag(); + switch (tg) { + case o("WAWebHandleGroupNotificationConst").GROUP_NOTIFICATION_TAG.REAL: + return {actionType:o("WAWebGroupType").GROUP_ACTIONS.FIRST, real:t.attrString("real")}; + } + }); + return {actions:x}; + } + l.handleGroupNotification=top; +}), 1); +"#; + +#[test] +fn the_action_union_is_the_switch_on_a_child_tag_not_the_biggest_one() { + // A module can hold several const-keyed switches. Choosing by arm count let an + // unrelated one — four returning arms against the union's one — publish its + // constants as wire tags. The union is identified by dispatching on a child's TAG. + let ir = extract_notif(DECOY_SWITCH_BUNDLE, "2.3000.test"); + let tags: Vec<&str> = notif(&ir, "w:gp2") + .actions + .iter() + .map(|a| a.wire_tag.as_str()) + .collect(); + assert_eq!( + tags, + ["real"], + "only the child-tag switch is the union: {tags:?}" + ); +} + +#[test] +fn a_shape_assigned_after_its_declaration_is_still_static() { + // `var lr; lr = {actionType: A, id: attr("jid")}; return lr` is fully static, but the + // reassignment rule required the right-hand side to resolve to a wire ACCESSOR and + // dropped the binding for an object literal, publishing an empty action. + let ir = extract_notif(GROUP_ACTIONS_EDGE_BUNDLE, "2.3000.test"); + let a = edge_action(&ir, "late"); + assert_eq!(a.action_type.as_deref(), Some("first")); + assert!( + a.fields + .iter() + .any(|f| f.name == "id" && f.wire_name == "jid"), + "the whole shape survives: {:?}", + a.fields + ); +} + +#[test] +fn a_do_while_body_write_is_definite() { + // A `do…while` body runs at least once, so every path reaching the return has run it. + // Grouping it with the zero-or-more loops tombstoned the write and lost the field. + let ir = extract_notif(GROUP_ACTIONS_EDGE_BUNDLE, "2.3000.test"); + let a = edge_action(&ir, "dow"); + assert!( + a.fields + .iter() + .any(|f| f.name == "id" && f.wire_name == "lid"), + "the body's write reaches the return: {:?}", + a.fields + ); +} + +#[test] +fn a_block_scoped_shadow_does_not_escape_its_block() { + // `var sh = a("jid"); { let sh = a("lid"); } return {id: sh}` reads `jid` — `let` dies + // with its block. Propagating the block's scope wholesale (the `var` fix) leaked it. + let ir = extract_notif(GROUP_ACTIONS_EDGE_BUNDLE, "2.3000.test"); + let a = edge_action(&ir, "shadow"); + let f = a + .fields + .iter() + .find(|f| f.name == "id") + .expect("the id field"); + assert_eq!( + f.wire_name, "jid", + "the OUTER binding is what the return reads" + ); +} + +#[test] +fn a_catch_parameter_shadows_the_outer_binding() { + // The catch parameter IS the caught exception, not whatever the outer scope bound to + // that name. Analyzing the handler against the unmodified scope published the catch + // arm's `id` as a read of `jid`. + let ir = extract_notif(GROUP_ACTIONS_EDGE_BUNDLE, "2.3000.test"); + let second: Vec<_> = notif(&ir, "w:gp2") + .actions + .iter() + .filter(|a| a.wire_tag == "catchp" && a.action_type.as_deref() == Some("second")) + .collect(); + assert_eq!(second.len(), 1, "the catch arm is recovered"); + assert!( + second[0].fields.is_empty(), + "but its `id` resolves to the exception, not to `jid`: {:?}", + second[0].fields + ); +} + +#[test] +fn nothing_after_an_exiting_do_while_is_reachable() { + // `do { return A } while (c); return B` — the body runs at least once and returns, so + // B is dead. `stmt_exits` had no `do…while` arm, so traversal walked on and published + // it as a second legal action. + let ir = extract_notif(GROUP_ACTIONS_EDGE_BUNDLE, "2.3000.test"); + let got: Vec<&str> = notif(&ir, "w:gp2") + .actions + .iter() + .filter(|a| a.wire_tag == "dowx") + .filter_map(|a| a.action_type.as_deref()) + .collect(); + assert_eq!(got, ["first"], "only the reachable shape: {got:?}"); +} + +#[test] +fn an_identical_read_on_both_ternary_branches_stays_required() { + // `c ? attrString("jid") : attrString("jid")` runs on every path and still rejects an + // absent `jid`. Falling through to the plain path made `read_field` see a conditional, + // call it a presence guard, and publish `required: false`. + let ir = extract_notif(GROUP_ACTIONS_EDGE_BUNDLE, "2.3000.test"); + let a = edge_action(&ir, "same"); + let f = a + .fields + .iter() + .find(|f| f.name == "id") + .expect("the id field"); + assert_eq!(f.wire_name, "jid"); + assert!(f.required, "the accessor is required on every path: {f:?}"); +} + +#[test] +fn a_nested_callback_object_is_not_flattened_into_the_child() { + // `{meta: {id: p.attrString("id")}, top: …}` — the element has `meta.id`, NOT a + // top-level `id`. Walking every property value reached the inner one and claimed it. + let ir = extract_notif(GROUP_ACTIONS_EDGE_BUNDLE, "2.3000.test"); + let a = edge_action(&ir, "nest"); + let child = a + .children + .iter() + .find(|c| c.name == "who") + .expect("the child"); + let names: Vec<&str> = child.fields.iter().map(|f| f.name.as_str()).collect(); + assert!( + names.contains(&"top"), + "the real flat field survives: {names:?}" + ); + assert!( + !names.contains(&"id"), + "the nested one is not hoisted: {names:?}" + ); +} + +#[test] +fn a_do_while_that_can_break_early_is_not_a_definite_write() { + // `do { if (c) break; x = a("lid"); } while (…)` reaches the return without assigning + // `x` on the break path, so `lid` is not its one certain source. + let ir = extract_notif(GROUP_ACTIONS_EDGE_BUNDLE, "2.3000.test"); + let a = edge_action(&ir, "dowb"); + assert!( + !a.fields.iter().any(|f| f.name == "id"), + "the early-exit path leaves it unbound: {:?}", + a.fields + ); +} + +#[test] +fn a_helper_given_a_wire_read_binds_its_parameter() { + // `function mk(v){ return {actionType: THIRD, id: v} }` called as + // `mk(t.attrString("jid"))`. The helper reads no attribute of its own, so expanding it + // with an empty scope resolved `v` to nothing and lost `id`. + let ir = extract_notif(GROUP_ACTIONS_EDGE_BUNDLE, "2.3000.test"); + let a = edge_action(&ir, "pval"); + assert_eq!(a.action_type.as_deref(), Some("third")); + let f = a + .fields + .iter() + .find(|f| f.name == "id") + .expect("the id field"); + assert_eq!(f.wire_name, "jid"); +} + +#[test] +fn a_break_consumed_by_a_do_while_does_not_end_the_case() { + // `do { break; } while (c); return B` reaches B — the `break` leaves the LOOP, not the + // case. Passing the enclosing `nested` down made `stmt_exits` treat it as an exit. + let ir = extract_notif(GROUP_ACTIONS_EDGE_BUNDLE, "2.3000.test"); + let got: Vec<&str> = notif(&ir, "w:gp2") + .actions + .iter() + .filter(|a| a.wire_tag == "dowbrk") + .filter_map(|a| a.action_type.as_deref()) + .collect(); + assert_eq!( + got, + ["second"], + "the statement after the loop is reachable: {got:?}" + ); +} + +#[test] +fn a_finalizer_write_is_definite() { + // A `finally` runs on every path, so what it assigns is certain at the return. + // Tombstoning the whole `try` statement removed the finalizer's own writes too. + let ir = extract_notif(GROUP_ACTIONS_EDGE_BUNDLE, "2.3000.test"); + let a = edge_action(&ir, "finw"); + let f = a + .fields + .iter() + .find(|f| f.name == "id") + .expect("the id field"); + assert_eq!( + f.wire_name, "lid", + "the finalizer's write is what reaches the return" + ); +} + +#[test] +fn a_for_initializer_runs_before_the_body() { + // `for (x = a("lid"); c; ) return {id: x}` always reads `lid`; analyzing the body + // against the pre-loop scope published the stale `jid`. + let ir = extract_notif(GROUP_ACTIONS_EDGE_BUNDLE, "2.3000.test"); + let second: Vec<_> = notif(&ir, "w:gp2") + .actions + .iter() + .filter(|a| a.wire_tag == "fori" && a.action_type.as_deref() == Some("second")) + .collect(); + assert_eq!(second.len(), 1); + let f = second[0] + .fields + .iter() + .find(|f| f.name == "id") + .expect("id"); + assert_eq!(f.wire_name, "lid"); +} + +#[test] +fn a_conditional_expression_write_tombstones_the_binding() { + // `cond && (x = a("lid"))` runs on some paths only, so `x` no longer has one known + // source. Ignoring the nested assignment left the pre-expression `jid` asserted. + let ir = extract_notif(GROUP_ACTIONS_EDGE_BUNDLE, "2.3000.test"); + let a = edge_action(&ir, "condw"); + assert!( + !a.fields + .iter() + .any(|f| f.name == "id" && f.wire_name == "jid"), + "the stale source must not be published: {:?}", + a.fields + ); +} + +#[test] +fn an_action_object_with_a_spread_is_refused() { + // `obj_props` skips the spread, so folding the survivors would publish a partial + // shape. A shape that cannot be read whole is refused, like the tables. + let ir = extract_notif(GROUP_ACTIONS_EDGE_BUNDLE, "2.3000.test"); + let a = edge_action(&ir, "sprd"); + assert!( + !a.fields.iter().any(|f| f.name == "id"), + "no partial shape is published: {:?}", + a.fields + ); +} diff --git a/crates/wa-scan/Cargo.toml b/crates/wa-scan/Cargo.toml index c47a137..b0e221c 100644 --- a/crates/wa-scan/Cargo.toml +++ b/crates/wa-scan/Cargo.toml @@ -22,3 +22,4 @@ wa-transform = { workspace = true } [dev-dependencies] anyhow = { workspace = true } +serde_json = { workspace = true } diff --git a/crates/wa-scan/src/enum_link.rs b/crates/wa-scan/src/enum_link.rs index 86b19c8..b1732ac 100644 --- a/crates/wa-scan/src/enum_link.rs +++ b/crates/wa-scan/src/enum_link.rs @@ -88,6 +88,99 @@ impl<'a> EnumResolver<'a> { } } + /// Fill in (or drop) the pending enum links on a response field tree. + /// + /// Same contract as the request side: a link whose enum resolves to a string-variant + /// set is kept, anything else is dropped rather than half-filled. The legacy scanner + /// records the reference without variants because it reads one module at a time; this + /// runs once the whole bundle index is available. + /// Returns the constraints it had to drop, keyed `site\x01module.ENUM@attr`, for + /// `dropsByReason` — an enum WA composes at runtime (`babelHelpers.extends({}, base, + /// {error: "error"})`, as the privacy settings do) has no literal value set to + /// recover, and that is worth reporting rather than leaving the field looking + /// unconstrained. + /// + /// `site` identifies the parser the loss belongs to, so two parsers losing the same + /// enum on the same attribute count as two — the smax counter learned this and this + /// pass repeated the site-less key. It must stay stable across the mirrored + /// `response.fields` / `response.variants` traversal of one parser, which is how the + /// same loss seen twice still counts once. + pub(crate) fn resolve_fields( + &mut self, + site: &str, + fields: &mut [wa_ir::ParsedField], + dropped: &mut std::collections::BTreeSet, + ) { + self.resolve_fields_at(site, "", fields, dropped) + } + + /// [`resolve_fields`], carrying the traversal `path` so two losses of the same table + /// on the same attribute under different children count as two. + /// + /// [`resolve_fields`]: EnumResolver::resolve_fields + fn resolve_fields_at( + &mut self, + site: &str, + path: &str, + fields: &mut [wa_ir::ParsedField], + dropped: &mut std::collections::BTreeSet, + ) { + for f in fields { + // Taken, not read: the pending reference is consumed here whether or not it + // resolves, so a second traversal of the same tree cannot count the same loss + // twice and nothing is left half-promoted. + if let Some(pending) = f.pending_enum_ref.take() { + let attr = f.wire_name.clone().unwrap_or_else(|| f.name.clone()); + // Both halves of the pending state are losses when they don't land: a + // link whose module export won't resolve, and a table that was never a + // resolvable reference at all. Counting only the first left the second + // looking like an enum with no constraint. + let lost = match pending { + wa_ir::PendingEnum::Link(er) => { + f.enum_ref = self.lookup(&er.module, &er.name); + f.enum_ref + .is_none() + .then(|| format!("{}.{}", er.module, er.name)) + } + wa_ir::PendingEnum::Unresolvable => Some("".to_string()), + }; + if let Some(what) = lost { + // The node PATH is part of the identity: one parser reading `state` + // off both `` and `` loses two constraints, and + // `site + table + attr` collapsed them into one. + dropped.insert(format!("{site}\u{1}{path}/{what}@{attr}")); + } + } + let here = format!("{path}/{}", f.tag.as_deref().unwrap_or(&f.name)); + if let Some(children) = &mut f.children { + self.resolve_fields_at(site, &here, children, dropped); + } + for uv in f.union_variants.iter_mut().flatten() { + self.resolve_fields_at(site, &here, &mut uv.fields, dropped); + } + } + } + + /// The resolved variants of `module::name`, memoized. `None` when the module is + /// absent, the export is not an enum, or a value is not a string. + fn lookup(&mut self, module: &str, name: &str) -> Option { + let module_slice = &self.module_slice; + let variants = self + .cache + .entry((module.to_string(), name.to_string())) + .or_insert_with(|| { + module_slice.get(module).and_then(|slice| { + wa_enums::resolve_named_enum(slice, module, name).and_then(variants_of) + }) + }) + .clone()?; + Some(AttrEnumRef { + name: name.to_string(), + module: module.to_string(), + variants, + }) + } + /// Resolve a flat list of attributes (a stanza root's own attrs). pub(crate) fn resolve_attrs(&mut self, attrs: &mut [WapAttrDef]) { for a in attrs { @@ -116,6 +209,81 @@ fn variants_of(def: wa_ir::InternalEnumDef) -> Option> { (!variants.is_empty()).then_some(variants) } +/// Cross-module resolution of the pending enum links a legacy parser leaves on a +/// response shape — the one public entry point for it. +/// +/// A parser records `o("Mod").ENUM` without variants because it reads a single module; +/// only a caller holding the whole bundle can finish the job. Every domain that runs +/// [`crate::parse_module_wap_parsers`] needs this, and the traversal it needs (the +/// shape's own fields *and* each variant's, under one site key) is written here once +/// instead of at each call site — the IQ scan had it, incoming and notif did not, and +/// their artifacts shipped links that resolved to nothing. +pub struct ResponseEnumLinker<'a> { + inner: EnumResolver<'a>, + /// Enum-link losses keyed `site\x01module.ENUM@attr`; see + /// [`EnumResolver::resolve_fields`]. + dropped: std::collections::BTreeSet, + /// Everything else the legacy scanner could not resolve, keyed the same way so two + /// occurrences in one parser count twice and the same one seen twice counts once. + other: std::collections::BTreeSet, +} + +impl<'a> ResponseEnumLinker<'a> { + pub fn new(defs: &'a [ModuleDefinition], source: &'a str) -> Self { + Self { + inner: EnumResolver::new(defs, source), + dropped: Default::default(), + other: Default::default(), + } + } + + /// Resolve every pending link in `shape`, attributing losses to `site`. + pub fn resolve(&mut self, site: &str, shape: &mut wa_ir::iq::ParsedResponse) { + self.inner + .resolve_fields(site, &mut shape.fields, &mut self.dropped); + for v in &mut shape.variants { + self.inner + .resolve_fields(site, &mut v.fields, &mut self.dropped); + } + // The legacy scanner parks its other unresolved constraints (a byte pin, a + // length band) on the shape because it has no diagnostics channel of its own. + // This is the one pass every domain runs, so it is where they get collected. + for d in shape.pending_drops.drain(..) { + self.other.insert(format!("{site}\u{1}{d}")); + } + } + + /// The enum links seen but not resolvable, for `dropsByReason`. + pub fn into_drops(self) -> std::collections::BTreeSet { + self.dropped + } + + /// Every loss this pass collected, grouped by `dropsByReason` key: the enum links + /// under [`crate::response_smax::ENUM_DROP`], plus whatever the legacy scanner + /// parked on the shapes, each already de-duplicated per site. + pub fn into_drop_counts(self) -> std::collections::BTreeMap { + let mut out: std::collections::BTreeMap = Default::default(); + if !self.dropped.is_empty() { + out.insert( + crate::response_smax::ENUM_DROP.to_string(), + self.dropped.len(), + ); + } + for key in self.other { + // `site\x01reason@detail` → the reason is what a reader groups by. + let reason = key + .split_once('\u{1}') + .map_or(key.as_str(), |(_, r)| r) + .split('@') + .next() + .unwrap_or("") + .to_string(); + *out.entry(reason).or_default() += 1; + } + out + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/crates/wa-scan/src/incoming.rs b/crates/wa-scan/src/incoming.rs index 967d12e..1cf2f55 100644 --- a/crates/wa-scan/src/incoming.rs +++ b/crates/wa-scan/src/incoming.rs @@ -20,6 +20,7 @@ use std::collections::{HashMap, HashSet}; use wa_ir::{AssertionKind, IncomingDef, IncomingTag}; use wa_transform::ModuleDefinition; +use crate::enum_link::ResponseEnumLinker; use crate::response::parse_module_wap_parsers; use crate::response_smax::{Resolver, analyze_module_exports}; @@ -40,8 +41,26 @@ fn incoming_tag(tag: &str) -> Option { /// `new WADeprecatedWapParser("…", fn)` whose body asserts a content tag, with its /// field tree recovered. pub fn scan_incoming_from_modules(source: &str, defs: &[ModuleDefinition]) -> Vec { + scan_incoming_with_diagnostics(source, defs).0 +} + +/// Like [`scan_incoming_from_modules`], but also returns the constraints the legacy +/// parsers carried and this domain could not resolve, by `dropsByReason` key. +/// +/// The counts existed only for IQ, so an unresolvable enum table in a received-stanza +/// parser produced a field with no legal values and no signal anywhere that a constraint +/// had been lost — exactly the distinction the pending marker was introduced to keep. +pub fn scan_incoming_with_diagnostics( + source: &str, + defs: &[ModuleDefinition], +) -> (Vec, std::collections::BTreeMap) { let mut out = Vec::new(); let mut seen = HashSet::new(); + // The legacy parser records `o("Mod").ENUM` as a pending link because it reads one + // module at a time; this domain has the whole bundle, so it runs the same + // cross-module post-pass the IQ scan does. Without it the links were simply lost — + // `message.type`'s `STANZA_MSG_TYPES` and `ALL_NONE` among them. + let mut enums = ResponseEnumLinker::new(defs, source); for m in defs { let slice = &source[m.start..m.end]; // Cheap pre-filter; the AST parse in `parse_module_wap_parsers` confirms the @@ -49,7 +68,7 @@ pub fn scan_incoming_from_modules(source: &str, defs: &[ModuleDefinition]) -> Ve if !slice.contains("WADeprecatedWapParser") || !seen.insert(m.name.as_str()) { continue; } - for shape in parse_module_wap_parsers(slice) { + for mut shape in parse_module_wap_parsers(slice) { // The parser's `assertTag("…")` is the received stanza's tag. // `assertTag("receipt")` stores the tag in the assertion's `name`. let tag = shape @@ -58,7 +77,13 @@ pub fn scan_incoming_from_modules(source: &str, defs: &[ModuleDefinition]) -> Ve .find(|a| a.kind == AssertionKind::Tag) .and_then(|a| a.name.as_deref()) .and_then(incoming_tag); + // The tag gate comes FIRST. This pass sees every legacy parser in the bundle, + // most of which belong to the IQ or notification domains; resolving before + // the gate charged their losses to `diagnostics.incoming`, which then + // described parsers absent from `incoming/index.json`. A diagnostic that does + // not describe the artifact beside it is worse than none. if let Some(tag) = tag { + enums.resolve(&format!("{}::{}", m.name, shape.parser_name), &mut shape); out.push(IncomingDef { tag, module: m.name.clone(), @@ -68,8 +93,12 @@ pub fn scan_incoming_from_modules(source: &str, defs: &[ModuleDefinition]) -> Ve } } // The smax-parsed `` read-shapes (a client publish's server ack) — a distinct - // mechanism the legacy pass above never sees. Merged into the same catalog. - out.extend(scan_incoming_smax_acks(source, defs)); + // mechanism the legacy pass above never sees. Merged into the same catalog, and so + // are its losses: that pass runs its own smax `Resolver`, whose drops used to be + // discarded, so the ack's `deprecatedEditMixin.edit` shipped as an enum with no + // values while this domain's `dropsByReason` stayed empty. + let (acks, ack_drops) = scan_incoming_smax_acks(source, defs); + out.extend(acks); // Deterministic order, independent of bundle layout; then drop exact // (tag, parser, module) duplicates (a parser re-declared verbatim). out.sort_by(|a, b| { @@ -81,7 +110,11 @@ pub fn scan_incoming_from_modules(source: &str, defs: &[ModuleDefinition]) -> Ve out.dedup_by(|a, b| { a.tag == b.tag && a.module == b.module && a.shape.parser_name == b.shape.parser_name }); - out + let mut drops = enums.into_drop_counts(); + for (reason, n) in ack_drops { + *drops.entry(reason).or_default() += n; + } + (out, drops) } /// A `WASmaxIn*Response{Success,Negative}` module whose root reads a top-level `` — @@ -99,7 +132,10 @@ fn is_smax_ack_response_module(name: &str) -> bool { /// that asserts the top-level `ack`, with its field tree (ack envelope + edit/revoke/paid /// sub-mixins and disjunctions) resolved through the shared [`Resolver`]. Mirrors the /// srvreq root pass; only the tag gate (`ack`, not the server-request set) differs. -fn scan_incoming_smax_acks(source: &str, defs: &[ModuleDefinition]) -> Vec { +fn scan_incoming_smax_acks( + source: &str, + defs: &[ModuleDefinition], +) -> (Vec, std::collections::BTreeMap) { // Every module name → slice (first occurrence wins; shard dedup) so the resolver can // chase the cross-module ack mixins these roots fold in. let mut slices: HashMap<&str, &str> = HashMap::new(); @@ -108,15 +144,26 @@ fn scan_incoming_smax_acks(source: &str, defs: &[ModuleDefinition]) -> Vec = Default::default(); for m in defs { if !is_smax_ack_response_module(&m.name) || !seen.insert(m.name.as_str()) { continue; } + // A resolver PER CANDIDATE, because this pass parses every `WASmaxIn*Response*` + // (88 of them) and keeps only the roots asserting `` (8). The rest are IQ + // responses whose losses must not be charged to this domain. + // + // Rewinding a shared collector was not enough: the resolver also memoizes the + // helpers it resolved, so a rejected module could record a loss on a shared + // helper, have it rewound, and then a later accepted ack would hit the cache and + // never record it again — an unconstrained field with an empty diagnostic. A + // discarded resolver takes its cache with it, so no rejected work can be + // observed at all. + let resolver = Resolver::new(&slices); let exports = analyze_module_exports(&source[m.start..m.end], &resolver); + let mut kept_any = false; for (name, shape) in &exports { // Skip inner child parsers: their export name extends another export's at a // word boundary (``), and their fields already nest in the @@ -149,14 +196,20 @@ fn scan_incoming_smax_acks(source: &str, defs: &[ModuleDefinition]) -> Vec HashSet { .collect() } +/// Extraction-quality counters the IQ scan hands back alongside the IR. +/// +/// Split from [`IqIr`] on purpose: these are *about* the extraction, not part of the +/// contract, and they exist so a silent regression (a WA refactor that hides a +/// construct we key on) shows up as a number rather than as a quietly emptier field. +#[derive(Debug, Clone, Default, PartialEq, Eq)] +pub struct IqScanStats { + /// Phase-2 fragment-merge recovery — see [`CrossModuleStats`]. + pub cross_module: CrossModuleStats, + /// Constraints seen in a response parser but not structurally resolvable, by reason + /// (an un-pinnable literal value, a computed reference path, an unresolvable enum + /// argument). Folded into `manifest.diagnostics.iq.dropsByReason`. + pub constraint_drops: std::collections::BTreeMap, +} + /// Cross-module (`mergeStanzas`, Phase 2) recovery counters for the IQ domain, /// surfaced in `manifest.diagnostics.iq.crossModule`. They make the Phase-2 fix /// visible and regressable: if a future bundle/codegen change silently broke @@ -120,12 +136,12 @@ pub fn scan_iq_stanzas_from_modules( scan_iq_with_diagnostics(source, module_defs).0 } -/// Like [`scan_iq_stanzas_from_modules`], but also returns the cross-module -/// (Phase 2) recovery counters for `manifest.diagnostics.iq.crossModule`. +/// Like [`scan_iq_stanzas_from_modules`], but also returns the extraction-quality +/// counters for `manifest.diagnostics.iq`. pub fn scan_iq_with_diagnostics( source: &str, module_defs: &[ModuleDefinition], -) -> (IqScanResult, CrossModuleStats) { +) -> (IqScanResult, IqScanStats) { // Build the cross-module helper index first. It resolves wap-returning helpers // (`xmppSignedPreKey`, `xmppPreKey`, …) so a child built via `o("Module").fn(...)` // / `.map(o("Module").fn)` recovers its subtree instead of leaving a bare node @@ -164,7 +180,8 @@ pub fn scan_iq_with_diagnostics( let mut stanzas = Vec::new(); let mut unparseable = Vec::new(); - let mut cross = CrossModuleStats::default(); + let mut stats = IqScanStats::default(); + let cross = &mut stats.cross_module; // The same module is often defined in several bundle shards (FB_PKG_DELIM); // scan each module name once so identical stanzas aren't emitted per shard // (and we don't redo the work). @@ -249,9 +266,21 @@ pub fn scan_iq_with_diagnostics( // filled in cross-module after the scan. (IQ attrs are namespace/type only, so // links here come from the request children.) let mut enum_resolver = enum_link::EnumResolver::new(module_defs, source); + let mut enum_linker = ResponseEnumLinker::new(module_defs, source); for s in &mut stanzas { enum_resolver.resolve_tree(&mut s.request.children); + // The response side needs the same pass, and gets it from the shared linker so + // the fields/variants traversal is not re-derived here. The parser, not the enum, + // is the unit of loss: two parsers that both fail to resolve `ENUM_OFF_ON` on + // `state` are two unrecovered constraints. + let site = format!("{}::{}", s.module_name, s.response.parser_name); + enum_linker.resolve(&site, &mut s.response); } + // Every reason the linker collected, not just the enum one: it also drains the + // legacy scanner's other unresolved constraints (a byte pin, a length band) off the + // shapes, and reading only `into_drops()` here discarded them — IQ reported no loss + // for exactly the constraints the previous round taught it to see. + let legacy_drops = enum_linker.into_drop_counts(); // Normalize ordering by an intrinsic key so the output (index.json + the // grouped codegen) is independent of bundle/source order, matching every @@ -274,7 +303,20 @@ pub fn scan_iq_with_diagnostics( stanzas, unparseable, }, - cross, + IqScanStats { + // Snapshotted only now: the request-anchored fallback builds its own resolver + // during the scan loop above and reports into the same shared collector, so + // reading it right after `build_pass` would miss every drop from precisely the + // unusual response shapes that fallback exists to handle. + constraint_drops: { + let mut d = response_index.drop_counts(); + for (reason, n) in legacy_drops { + *d.entry(reason).or_default() += n; + } + d + }, + ..stats + }, ) } @@ -298,22 +340,21 @@ pub fn extract_iq_from_modules( extract_iq_from_modules_with_diagnostics(source, module_defs, wa_version).0 } -/// Like [`extract_iq_from_modules`], but also returns the cross-module (Phase 2) -/// recovery counters so the pipeline can record them under -/// `manifest.diagnostics.iq.crossModule`. +/// Like [`extract_iq_from_modules`], but also returns the extraction-quality counters +/// so the pipeline can record them under `manifest.diagnostics.iq`. pub fn extract_iq_from_modules_with_diagnostics( source: &str, module_defs: &[ModuleDefinition], wa_version: &str, -) -> (IqIr, CrossModuleStats) { - let (scan, cross) = scan_iq_with_diagnostics(source, module_defs); +) -> (IqIr, IqScanStats) { + let (scan, stats) = scan_iq_with_diagnostics(source, module_defs); ( IqIr { wa_version: wa_version.to_string(), stanzas: scan.stanzas, unparseable: scan.unparseable, }, - cross, + stats, ) } @@ -410,9 +451,9 @@ mod tests { // Diagnostics: exactly the Request folds in a mixin and is enriched by it; // only `spam_flow` is new (`jid` was already local), so one field recovered. - assert_eq!(cross.requests_with_mixins, 1); - assert_eq!(cross.requests_enriched, 1); - assert_eq!(cross.fields_recovered, 1); + assert_eq!(cross.cross_module.requests_with_mixins, 1); + assert_eq!(cross.cross_module.requests_enriched, 1); + assert_eq!(cross.cross_module.fields_recovered, 1); } #[test] diff --git a/crates/wa-scan/src/response.rs b/crates/wa-scan/src/response.rs index 26a5e58..0914f00 100644 --- a/crates/wa-scan/src/response.rs +++ b/crates/wa-scan/src/response.rs @@ -61,6 +61,7 @@ pub(crate) fn parsed_response_from_new_expr( parser_name: name, assertions: result.assertions, fields: result.fields, + pending_drops: result.unresolved, ..Default::default() }) } @@ -158,14 +159,23 @@ impl<'a> Visit<'a> for ParserCollector<'_> { pub(crate) struct ParserResult { pub assertions: Vec, pub fields: Vec, + /// See [`ParsedResponse::pending_drops`]. + pub unresolved: Vec, } -/// Accessors that read a value off a node, as the parser treats them: the shared -/// attribute accessors ([`wap::is_attr_method`]) plus the `contentBytes` / -/// `contentString` leaves. Broader than codegen's notion of an attr field — both +/// Accessors that read a value off a node, as the parser treats them: every shared +/// attribute accessor ([`wap::is_attr_method`]) plus every content leaf +/// ([`wap::is_content_method`]). Broader than codegen's notion of an attr field — both /// draw method names from the shared [`wap`] vocabulary so they can't drift. -fn is_attr_method(m: &str) -> bool { - wap::is_attr_method(m) || m == wap::CONTENT_BYTES || m == wap::CONTENT_STRING +/// +/// Both halves are *derived*. Naming `contentBytes`/`contentString` here and nothing +/// else was the enumerate-vs-derive bug a third time: `method_field_type` learned to +/// decode `contentUint`, `contentEnum`, `contentBytesRange` and `contentLiteralBytes`, +/// but this list did not, so on the legacy path those reads produced no typed field at +/// all — only a coarse `contentType` on the parent, losing the integer, enum, range and +/// literal constraints. +fn is_value_method(m: &str) -> bool { + wap::is_attr_method(m) || wap::is_content_method(m) } fn is_assert_method(m: &str) -> bool { @@ -202,19 +212,149 @@ fn mk_field(method: &str, name: &str, ftype: ParsedFieldType, required: bool) -> /// the field name (else `"content"`), and capturing the `contentBytes(N)` byte length /// when the first argument is a numeric literal — the length WA Web's parser pins the /// wire field to (`child("signature").contentBytes(64)` → 64). -fn field_from_call(method: &str, call: &CallExpression) -> ParsedField { +/// The `o("Mod").ENUM_NAME` table an enum-valued accessor validates against, as a +/// **pending** [`wa_ir::AttrEnumRef`] — name and module filled, variants empty. +/// +/// The legacy scanner sees one module at a time and cannot read another's exports, so it +/// records the reference and [`crate::enum_link`] fills it in a post-pass, the same +/// convention the request-attribute enums already use. Without this the field shipped as +/// `"type": "enum"` with nothing saying which values are legal — 98 of them. +fn pending_enum_ref(method: &str, call: &CallExpression, module_scope: &ModuleScope) -> EnumSource { + if wap::method_field_type(method) != ParsedFieldType::Enum { + return EnumSource::NotAnEnum; + } + // A content accessor takes its table as the FIRST argument (`contentEnum(TABLE)`); + // an attribute one names the attribute first (`attrStringEnum("state", TABLE)`). + // Reading past the name unconditionally found nothing on the content spellings. + let skip = usize::from(!wap::is_content_method(method)); + let Some(arg) = call.arguments.iter().skip(skip).filter_map(arg_expr).next() else { + return EnumSource::Unresolved; + }; + // `attrEnumValues("type", o("Mod").CiphertextType.members())` — the allowed set is + // the enum's `.members()`, so the table is the *callee's object*, not the call. + let stripped = strip_members_call(arg); + let via_members = !std::ptr::eq(stripped, arg); + let arg = stripped; + // FORM A: a cross-module export. Recorded as pending; `enum_link` finishes it. + if let Some((obj, name)) = wa_oxc::as_member(arg) + && let Some(module) = wa_oxc::as_call(obj) + .and_then(|c| c.arguments.first()) + .and_then(arg_expr) + .and_then(as_string_lit) + { + return EnumSource::Pending(wa_ir::AttrEnumRef { + name: name.to_string(), + module: module.to_string(), + variants: Vec::new(), + }); + } + // FORM B: a module-local table (`attrEnumValues("mediatype", u.members())`, where + // `u = n("$InternalEnum")({Image: "image", …})`). The allowed set is already in this + // module, so it becomes `enumKeys` directly — no cross-module post-pass, and no + // `enumRef` named after a minified local. + if let Some(name) = as_identifier(arg) { + let table = if via_members { + module_scope.members.get(name) + } else { + module_scope.maps.get(name) + }; + if let Some(values) = table.filter(|v| !v.is_empty()) { + return EnumSource::Keys(values.clone()); + } + } + EnumSource::Unresolved +} + +/// Where an enum accessor's allowed-value set came from. +/// +/// `Unresolved` exists so an enum whose table is not structurally recoverable is +/// *counted* rather than published as an unconstrained `"type": "enum"` — the same +/// "missing beats wrong, but never silent" rule the rest of the scan follows. +enum EnumSource { + NotAnEnum, + Pending(wa_ir::AttrEnumRef), + Keys(Vec), + Unresolved, +} + +/// Unwrap a trailing `.members()` / `.getMembers()` accessor, which WA uses to spell +/// "the allowed values of this enum"; anything else is returned unchanged. +fn strip_members_call<'b, 'a>(e: &'b Expression<'a>) -> &'b Expression<'a> { + wa_oxc::as_call(e) + .filter(|c| c.arguments.is_empty()) + .and_then(|c| match callee_method(c) { + Some("members" | "getMembers") => callee_object(c), + _ => None, + }) + .unwrap_or(e) +} + +fn field_from_call( + method: &str, + call: &CallExpression, + module_scope: &ModuleScope, + unresolved: &mut Vec, +) -> ParsedField { let arg0 = call.arguments.first().and_then(arg_expr); - let field_name = arg0.and_then(as_string_lit).unwrap_or("content"); + // A content accessor reads the element's content and names no attribute, so its + // first argument is never the field name — `contentEnum(TABLE)` would otherwise be + // named after nothing at all. + let field_name = if wap::is_content_method(method) { + "content" + } else { + arg0.and_then(as_string_lit).unwrap_or("content") + }; let mut f = mk_field( method, field_name, method_to_field_type(method), is_method_required(method), ); - if method == wap::CONTENT_BYTES - && let Some(Expression::NumericLiteral(n)) = arg0 - { - f.byte_length = Some(n.value as u32); + // Each byte accessor pins something different, and routing them all here without + // reading their arguments published unconstrained `bytes` — an emitter would think + // any payload passes where the parser accepts one sequence or one length band. + match method { + // `contentBytes(64)` and `contentUint(3)` both take a BYTE COUNT. `contentUint` + // is not a decimal string: WA packs a prekey id into 3 bytes and a registration + // id into 4, big-endian, so the length is part of the wire contract and dropping + // it left the field looking like unbounded text. + wap::CONTENT_BYTES | "contentUint" => { + if let Some(Expression::NumericLiteral(n)) = arg0 { + f.byte_length = Some(n.value as u32); + } + } + // `contentLiteralBytes(new Uint8Array([5]))` — the node is the receiver on this + // path, so the sequence is argument 0 (smax passes the node first). + "contentLiteralBytes" => match arg0.and_then(crate::response_smax::static_byte_literal) { + Some(bytes) => { + f.byte_length = Some(bytes.len() as u32); + f.literal_value = Some(bytes.iter().map(|b| format!("{b:02x}")).collect()); + } + None => unresolved.push(format!("contentLiteralBytes@{field_name}")), + }, + // `contentBytesRange(min, max)` — a payload-size band. `min == max` is a fixed + // length, which `byte_length` already expresses. + "contentBytesRange" => { + let bound = |i: usize| match call.arguments.get(i).and_then(arg_expr) { + Some(Expression::NumericLiteral(n)) => Some(n.value as u32), + _ => None, + }; + match (bound(0), bound(1)) { + (Some(min), Some(max)) if min == max => f.byte_length = Some(min), + (Some(min), Some(max)) => { + f.byte_min = Some(min); + f.byte_max = Some(max); + } + _ => unresolved.push(format!("contentBytesRange@{field_name}")), + } + } + _ => {} + } + match pending_enum_ref(method, call, module_scope) { + EnumSource::Pending(er) => f.pending_enum_ref = Some(wa_ir::PendingEnum::Link(er)), + EnumSource::Keys(keys) => f.enum_keys = Some(keys), + EnumSource::Unresolved => f.pending_enum_ref = Some(wa_ir::PendingEnum::Unresolvable), + EnumSource::NotAnEnum => {} } f } @@ -285,6 +425,8 @@ fn analyze_with_scope(code: &str, param: &str, module: &ModuleScope) -> ParserRe fields: Vec::new(), child_vars: HashMap::new(), pending_enum_keys: HashMap::new(), + unresolved_enum_attrs: Default::default(), + unresolved: Vec::new(), helper_depth: 0, }; a.visit_program(&ret.program); @@ -292,6 +434,7 @@ fn analyze_with_scope(code: &str, param: &str, module: &ModuleScope) -> ParserRe ParserResult { assertions: a.assertions, fields: a.fields, + unresolved: a.unresolved, } } @@ -311,6 +454,14 @@ struct ParserAnalyzer<'src, 'ms> { /// (the map is module-scope, so it's resolved and stashed here, then attached to the /// matching field in a post-pass — order-independent of the plain read of the attr). pending_enum_keys: HashMap>, + /// Wire attributes read by `attrEnumOrNullIfUnknown` whose allowed-value table could + /// not be named. Resolved in [`ParserAnalyzer::attach_pending_enum_keys`] alongside + /// the ones that did resolve. + unresolved_enum_attrs: std::collections::BTreeSet, + /// Constraints seen on this parser but not statically resolvable, as + /// `dropsByReason` keys. Parked on the produced [`ParsedResponse`] for whoever + /// finishes it, since the legacy scanner has no diagnostics channel of its own. + unresolved: Vec, /// Recursion guard for module-scope helper descent (`m(n,i)` → analyze `m`'s body). helper_depth: u32, } @@ -372,6 +523,7 @@ impl ParserAnalyzer<'_, '_> { kind: AssertionKind::Tag, name: Some(v.to_string()), value: None, + reference_path: None, }); } } @@ -381,6 +533,7 @@ impl ParserAnalyzer<'_, '_> { kind: AssertionKind::Attr, name: Some(name.to_string()), value: arg_str(call, 1).map(str::to_string), + reference_path: None, }); } } @@ -388,6 +541,7 @@ impl ParserAnalyzer<'_, '_> { kind: AssertionKind::FromServer, name: None, value: None, + reference_path: None, }), _ => {} } @@ -402,28 +556,43 @@ impl ParserAnalyzer<'_, '_> { && obj_is_param && let Some(wire) = arg_str(call, 0) { - if let Some(keys) = call + match call .arguments .get(1) .and_then(arg_expr) .and_then(as_identifier) .and_then(|m| self.module.maps.get(m).cloned()) { - self.pending_enum_keys - .entry(wire.to_string()) - .or_insert(keys); + Some(keys) => { + self.pending_enum_keys + .entry(wire.to_string()) + .or_insert(keys); + } + // The table is not a module-scope identifier — `o("Mod").TABLE`, or a + // computed set. The parser still enforces an enum here, so returning + // silently produced neither a link nor a drop and the new diagnostics + // reported nothing lost. Recorded so it is counted, and so a field gets + // synthesized when no companion read created one. + None => { + self.unresolved_enum_attrs.insert(wire.to_string()); + } } return; } // ── Attr/content accessor on the param directly ── - if is_attr_method(method) && obj_is_param { - self.fields.push(field_from_call(method, call)); + if is_value_method(method) && obj_is_param { + self.fields.push(field_from_call( + method, + call, + self.module, + &mut self.unresolved, + )); return; } // ── Attr method chained on a child() result: e.child("error").attrInt("code") ── - if is_attr_method(method) + if is_value_method(method) && let Some((parent_tag, inner_method)) = self.child_call_parent(obj) { let idx = find_or_create_field( @@ -432,7 +601,11 @@ impl ParserAnalyzer<'_, '_> { inner_method, inner_method == "child", ); - push_child_field(&mut self.fields, idx, field_from_call(method, call)); + push_child_field( + &mut self.fields, + idx, + field_from_call(method, call, self.module, &mut self.unresolved), + ); return; } @@ -483,13 +656,17 @@ impl ParserAnalyzer<'_, '_> { } // ── Attr methods on a tracked child var: t.attrString("name") ── - if is_attr_method(method) + if is_value_method(method) && let Some(parent_tag) = as_identifier(obj) .and_then(|n| self.child_vars.get(n)) .cloned() { let idx = find_or_create_field(&mut self.fields, &parent_tag, "child", true); - push_child_field(&mut self.fields, idx, field_from_call(method, call)); + push_child_field( + &mut self.fields, + idx, + field_from_call(method, call, self.module, &mut self.unresolved), + ); } // ── content methods on a tracked child var ── @@ -590,6 +767,20 @@ impl ParserAnalyzer<'_, '_> { { if f.enum_keys.is_none() { f.enum_keys = Some(keys); + // Retype the companion read. The plain `maybeAttrString("type")` beside + // `attrEnumOrNullIfUnknown("type", map)` is the SAME wire attribute + // validated against that key set, so leaving it `type: "string"` while + // hanging nine `enumKeys` off it hid the constraint from every consumer + // that selects enum fields by `type == "enum"` — the incoming receipt's + // `type` shipped exactly that way. + let optional = wap::is_optional_method(&f.method); + f.method = if optional { + wap::MAYBE_ATTR_ENUM.to_string() + } else { + wap::ATTR_ENUM.to_string() + }; + f.field_type = ParsedFieldType::Enum; + f.required = !optional; } } else { // No companion plain read created a field for this attr (doesn't occur in @@ -598,11 +789,39 @@ impl ParserAnalyzer<'_, '_> { // optional attr validated against an enum key set, which is exactly // `maybeAttrEnum`. A raw "attrEnumOrNullIfUnknown" method would not be in // `wap::is_attr_method`, leaving the field unclassified downstream. - let mut f = mk_field(wap::MAYBE_ATTR_ENUM, &wire, ParsedFieldType::String, false); + let mut f = mk_field(wap::MAYBE_ATTR_ENUM, &wire, ParsedFieldType::Enum, false); f.enum_keys = Some(keys); self.fields.push(f); } } + // The same two halves for a table that could NOT be named: mark the companion read + // as an enum with an unrecoverable value set, or synthesize the field, so the + // constraint is counted either way instead of vanishing. + for wire in std::mem::take(&mut self.unresolved_enum_attrs) { + match self + .fields + .iter_mut() + .find(|f| f.name == wire && f.tag.is_none()) + { + Some(f) if f.enum_keys.is_none() && f.pending_enum_ref.is_none() => { + let optional = wap::is_optional_method(&f.method); + f.method = if optional { + wap::MAYBE_ATTR_ENUM.to_string() + } else { + wap::ATTR_ENUM.to_string() + }; + f.field_type = ParsedFieldType::Enum; + f.required = !optional; + f.pending_enum_ref = Some(wa_ir::PendingEnum::Unresolvable); + } + Some(_) => {} + None => { + let mut f = mk_field(wap::MAYBE_ATTR_ENUM, &wire, ParsedFieldType::Enum, false); + f.pending_enum_ref = Some(wa_ir::PendingEnum::Unresolvable); + self.fields.push(f); + } + } + } } } @@ -619,6 +838,9 @@ struct ModuleScope { /// object-map name → its keys in source order — the allowed value set an enum accessor /// (`attrEnumOrNullIfUnknown("attr", map)`) validates a wire attr against. maps: HashMap>, + /// The same maps by their string *values* — what `.members()` yields for a + /// module-local enum (`attrEnumValues("mediatype", u.members())`). + members: HashMap>, } impl ModuleScope { @@ -635,12 +857,14 @@ impl ModuleScope { module_source, functions: HashMap::new(), maps: HashMap::new(), + members: HashMap::new(), fn_depth: 0, }; b.visit_program(&ret.program); Self { functions: b.functions, maps: b.maps, + members: b.members, } } } @@ -649,6 +873,7 @@ struct ModuleScopeBuilder<'a> { module_source: &'a str, functions: HashMap, String)>, maps: HashMap>, + members: HashMap>, /// Number of function bodies we are currently inside. The bundle wraps every module /// in one factory (`__d("M",…,function(…){ })`), so a module-scope /// sibling helper — the only kind `try_helper_descent` may resolve a bare-identifier @@ -709,14 +934,52 @@ impl<'a> Visit<'a> for ModuleScopeBuilder<'_> { self.record_fn(name.as_str(), &f.params, body.span); } } - // `var name = { key: val, … }` — an enum value map. + // `var name = { key: val, … }` — an enum value map — or the same object + // wrapped in a one-argument factory, which is how WA declares a + // module-local enum: `var u = n("$InternalEnum")({Image: "image", …})`. + // Only a factory-body-level (depth 1) binding is module-scope, the same + // gate the helper branch above uses. Recording at ANY depth let two + // parsers reusing one minified name share a table: the second `u.members()` + // resolved to the first parser's values and published a closed `enumKeys` + // set that is simply wrong — an invented constraint, worse than a lost one. _ => { - if let Some(obj) = wa_oxc::as_object(init) { - self.maps - .entry(name.as_str().to_string()) - .or_insert_with(|| { - wa_oxc::obj_props(obj).map(|(k, _)| k.to_string()).collect() - }); + if self.fn_depth != 1 { + walk::walk_variable_declarator(self, d); + return; + } + let obj = wa_oxc::as_object(init).or_else(|| { + wa_oxc::as_call(init) + .filter(|c| c.arguments.len() == 1) + .and_then(|c| arg_expr(&c.arguments[0])) + .and_then(wa_oxc::as_object) + }); + // `obj_props` silently skips a spread, a method and a computed key, + // so an object containing one yields a SHORTER list that still + // collects successfully — publishing a closed set that claims the + // parser rejects whatever the skipped property contributed. A table + // we cannot read whole is not a table. + let obj = obj.filter(|o| o.properties.len() == wa_oxc::obj_props(o).count()); + if let Some(obj) = obj { + let n = name.as_str().to_string(); + // Keys and values are both allowed-value sets, for *different* + // accessors: `attrEnumOrNullIfUnknown("t", map)` validates against + // the keys, while `attrEnumValues("t", enum.members())` validates + // against the members — the wire values. Recording only the keys + // left every `.members()` table unresolvable. + self.maps.entry(n.clone()).or_insert_with(|| { + wa_oxc::obj_props(obj).map(|(k, _)| k.to_string()).collect() + }); + // All-or-nothing, like the cross-module resolver's `variants_of`: + // `{A: "a", B: computed}` must not publish `["a"]` as the complete + // set — that is an enum the IR says rejects `B` when the runtime + // accepts it. An incomplete table is left absent and the accessor + // is counted as unresolved instead. + let members: Option> = wa_oxc::obj_props(obj) + .map(|(_, v)| as_string_lit(v).map(str::to_string)) + .collect(); + if let Some(members) = members.filter(|m| !m.is_empty()) { + self.members.entry(n).or_insert(members); + } } } } @@ -750,6 +1013,8 @@ fn analyze_child_node( fields: Vec::new(), child_vars: HashMap::from([(node_param.to_string(), tag.to_string())]), pending_enum_keys: HashMap::new(), + unresolved_enum_attrs: Default::default(), + unresolved: Vec::new(), helper_depth: depth, }; a.visit_program(&ret.program); @@ -778,11 +1043,13 @@ fn merge_child_shape(fields: &mut [ParsedField], tag: &str, new_children: Vec ContentType { - if method == "contentBytes" { - ContentType::Bytes - } else { - ContentType::String + match wap::method_field_type(method) { + ParsedFieldType::Bytes => ContentType::Bytes, + ParsedFieldType::Integer => ContentType::Integer, + _ => ContentType::String, } } @@ -1299,4 +1566,256 @@ mod tests { Some(["delivery", "read", "played"].map(String::from).as_slice()) ); } + + #[test] + fn an_unnameable_enum_table_is_still_counted() { + // `attrEnumOrNullIfUnknown("type", o("Mod").TABLE)` — the table is not a + // module-scope identifier, so the fast path missed and returned, producing no + // link, no drop and (with no companion read) no field. The parser enforces an + // enum there; a silent loss is the one outcome this change exists to prevent. + let module = r#"__d("M",["WADeprecatedWapParser"],(function(t,n,r,o,a,i,l){ + var c=new(r("WADeprecatedWapParser"))("p", function(e){ + e.assertTag("receipt"); + var t=e.attrEnumOrNullIfUnknown("type", o("Other").TABLE); + return {}; + }); + }),1);"#; + let out = parse_module_wap_parsers(module); + let p = out.iter().find(|r| r.parser_name == "p").expect("parser"); + let f = p + .fields + .iter() + .find(|f| f.name == "type") + .expect("the field is synthesized rather than vanishing"); + assert_eq!(f.field_type, ParsedFieldType::Enum); + assert_eq!(f.pending_enum_ref, Some(wa_ir::PendingEnum::Unresolvable)); + assert!(f.enum_keys.is_none(), "and no invented value set"); + } + + #[test] + fn a_companion_read_is_retyped_when_it_gains_enum_keys() { + // `attrEnumOrNullIfUnknown("type", map)` beside a plain `maybeAttrString("type")` + // is the SAME attribute validated against that key set. Hanging `enumKeys` off the + // companion while leaving it `type: "string"` hid the constraint from every + // consumer that selects enum fields by `type == "enum"`. + let module = r#"__d("M",["WADeprecatedWapParser"],(function(t,n,r,o,a,i,l){ + var u={delivery:1,read:2}; + var c=new(r("WADeprecatedWapParser"))("p", function(e){ + e.assertTag("receipt"); + var t=e.hasAttr("type")?e.attrEnumOrNullIfUnknown("type",u):0; + e.maybeAttrString("type"); + return {}; + }); + }),1);"#; + let out = parse_module_wap_parsers(module); + let p = out.iter().find(|r| r.parser_name == "p").expect("parser"); + let f = p + .fields + .iter() + .find(|f| f.name == "type" && f.tag.is_none()) + .expect("the type field"); + assert_eq!( + f.field_type, + ParsedFieldType::Enum, + "retyped, not just annotated" + ); + assert_eq!( + f.method, + wap::MAYBE_ATTR_ENUM, + "and under the enum accessor" + ); + assert!(!f.required, "the companion read was optional and stays so"); + assert_eq!( + f.enum_keys.as_deref(), + Some(["delivery", "read"].map(String::from).as_slice()) + ); + } + + #[test] + fn a_typed_content_accessor_becomes_a_typed_field() { + // `contentUint` was outside the local attr/content list, so a read of it produced + // no field at all — only a coarse `contentType` on the parent. Both halves of the + // predicate are derived from `wap` now, so every spelling `method_field_type` + // decodes reaches field extraction. + let r = analyze_parser_ast(r#"{ e.child("registration").contentUint(); }"#, "e"); + let parent = r + .fields + .iter() + .find(|f| f.tag.as_deref() == Some("registration")) + .expect("the child is recovered"); + let leaf = parent + .children + .as_ref() + .and_then(|c| c.first()) + .expect("its content read is a field"); + assert_eq!(leaf.method, "contentUint"); + assert_eq!(leaf.field_type, ParsedFieldType::Integer); + assert_eq!(leaf.name, "content", "a content read names no attribute"); + } + + #[test] + fn attr_enum_values_recovers_a_module_local_enums_members() { + // `attrEnumValues("mediatype", u.members())` where `u` is a module-local + // `$InternalEnum`. The table is neither an `o("Mod").ENUM` member (so the + // cross-module post-pass cannot see it) nor a bare map identifier — it is the + // enum's VALUES. Reading past the `.members()` call and taking the values is what + // turns an apparently unconstrained `"type": "enum"` into the legal set. + let module = r#"__d("M",["WADeprecatedWapParser"],(function(t,n,r,o,a,i,l){ + var u=n("$InternalEnum")({Image:"image",Video:"video"}); + var c=new(r("WADeprecatedWapParser"))("p", function(e){ + e.assertTag("message"); + e.child("media").attrEnumValues("mediatype", u.members()); + return {}; + }); + }),1);"#; + let out = parse_module_wap_parsers(module); + let p = out.iter().find(|r| r.parser_name == "p").expect("parser"); + let media = p + .fields + .iter() + .find(|f| f.tag.as_deref() == Some("media")) + .expect("the child"); + let field = media + .children + .as_ref() + .and_then(|c| c.iter().find(|f| f.name == "mediatype")) + .expect("the mediatype attr"); + assert_eq!( + field.enum_keys.as_deref(), + Some(["image", "video"].map(String::from).as_slice()), + "`.members()` yields the enum's VALUES, not its keys" + ); + } + + #[test] + fn an_unresolvable_enum_table_is_marked_pending_not_silently_dropped() { + // An enum accessor whose table is a computed expression must be distinguishable + // from a field that is not an enum at all — the first is a constraint we failed + // to extract and belongs in `dropsByReason`. + let r = analyze_parser_ast(r#"{ e.attrStringEnum("state", pick()); }"#, "e"); + let f = r.fields.iter().find(|f| f.name == "state").expect("field"); + assert_eq!(f.pending_enum_ref, Some(wa_ir::PendingEnum::Unresolvable)); + assert!(f.enum_keys.is_none() && f.enum_ref.is_none()); + } + + #[test] + fn legacy_byte_accessors_keep_the_constraint_they_pin() { + // Routing the typed content accessors into field extraction is only half the job: + // `field_from_call` read the argument of plain `contentBytes` and nothing else, so + // these two published unconstrained bytes — an emitter would think any payload + // passes where the parser accepts one sequence, or one length band. + let r = analyze_parser_ast( + r#"{ e.child("t").contentLiteralBytes(Uint8Array.of(5, 255)); + e.child("blob").contentBytesRange(1, 128); }"#, + "e", + ); + let leaf = |tag: &str| { + r.fields + .iter() + .find(|f| f.tag.as_deref() == Some(tag)) + .and_then(|f| f.children.as_ref()) + .and_then(|c| c.first()) + .unwrap_or_else(|| panic!("no leaf under <{tag}>")) + .clone() + }; + let pinned = leaf("t"); + assert_eq!(pinned.literal_value.as_deref(), Some("05ff")); + assert_eq!(pinned.byte_length, Some(2)); + let ranged = leaf("blob"); + assert_eq!((ranged.byte_min, ranged.byte_max), (Some(1), Some(128))); + assert_eq!( + ranged.byte_length, None, + "a true range is not a fixed length" + ); + } + + #[test] + fn a_zero_filled_uint8array_is_a_recoverable_pin() { + // `new Uint8Array(4)` is a LENGTH — and therefore exactly four zero bytes, as much + // a compile-time constant as a literal array. Refusing it lost a recoverable pin; + // reading the `4` as the byte 0x04 would have invented a different one. + let r = analyze_parser_ast( + r#"{ e.child("nonce").contentLiteralBytes(new Uint8Array(4)); }"#, + "e", + ); + let leaf = r.fields[0].children.as_ref().unwrap()[0].clone(); + assert_eq!(leaf.literal_value.as_deref(), Some("00000000")); + assert_eq!(leaf.byte_length, Some(4)); + assert!(r.unresolved.is_empty(), "and nothing is reported lost"); + } + + #[test] + fn an_unresolvable_byte_pin_is_reported_not_published_as_free_bytes() { + let r = analyze_parser_ast(r#"{ e.child("t").contentLiteralBytes(computed()); }"#, "e"); + assert!( + r.unresolved + .iter() + .any(|d| d.starts_with("contentLiteralBytes@")), + "the loss is counted: {:?}", + r.unresolved + ); + } + + #[test] + fn a_byte_pin_from_a_foreign_factory_is_not_trusted() { + // `factory.of(1, 2)` is an ordinary call that may return anything; reading its + // arguments as the pinned bytes would invent a `literalValue` rather than record + // an unresolved one. Same for `new Whatever([1, 2])`. + for src in [ + r#"{ e.child("t").contentLiteralBytes(factory.of(1, 2)); }"#, + r#"{ e.child("t").contentLiteralBytes(new Whatever([1, 2])); }"#, + ] { + let r = analyze_parser_ast(src, "e"); + let leaf = r.fields[0].children.as_ref().unwrap()[0].clone(); + assert_eq!(leaf.literal_value, None, "no invented pin for {src}"); + assert!( + r.unresolved + .iter() + .any(|d| d.starts_with("contentLiteralBytes@")), + "and the loss is counted for {src}" + ); + } + } + + #[test] + fn a_table_with_a_spread_is_not_a_complete_table() { + // `obj_props` silently skips a spread, so the surviving literals collected + // successfully and were published as a CLOSED set — claiming the parser rejects + // whatever the spread contributed. An invented constraint, not a lost one. + let module = r#"__d("M",["WADeprecatedWapParser"],(function(t,n,r,o,a,i,l){ + var u=n("$InternalEnum")({A:"a", ...base}); + var c=new(r("WADeprecatedWapParser"))("p", function(e){ + e.assertTag("message"); + e.attrEnumValues("k", u.members()); + return {}; + }); + }),1);"#; + let out = parse_module_wap_parsers(module); + let p = out.iter().find(|r| r.parser_name == "p").expect("parser"); + let f = p.fields.iter().find(|f| f.name == "k").expect("field"); + assert!( + f.enum_keys.is_none(), + "an unreadable table is not a value set" + ); + assert_eq!(f.pending_enum_ref, Some(wa_ir::PendingEnum::Unresolvable)); + } + + #[test] + fn a_partially_literal_enum_table_is_refused_whole() { + // `{A: "a", B: computed}` must not publish `["a"]` as the complete legal set — + // that is an enum the IR says rejects `B` while the runtime accepts it. + let module = r#"__d("M",["WADeprecatedWapParser"],(function(t,n,r,o,a,i,l){ + var u=n("$InternalEnum")({A:"a",B:pick()}); + var c=new(r("WADeprecatedWapParser"))("p", function(e){ + e.assertTag("message"); + e.attrEnumValues("k", u.members()); + return {}; + }); + }),1);"#; + let out = parse_module_wap_parsers(module); + let p = out.iter().find(|r| r.parser_name == "p").expect("parser"); + let f = p.fields.iter().find(|f| f.name == "k").expect("field"); + assert!(f.enum_keys.is_none(), "an incomplete table is not the set"); + assert_eq!(f.pending_enum_ref, Some(wa_ir::PendingEnum::Unresolvable)); + } } diff --git a/crates/wa-scan/src/response_index.rs b/crates/wa-scan/src/response_index.rs index 6bdd8b8..68e2496 100644 --- a/crates/wa-scan/src/response_index.rs +++ b/crates/wa-scan/src/response_index.rs @@ -12,9 +12,13 @@ use std::collections::{BTreeMap, HashMap, HashSet}; -use wa_ir::{ParsedField, ParsedFieldType, ParsedResponse, ResponseVariant, ResponseVariantKind}; +use wa_ir::{ + ErrorArm, ParsedField, ParsedFieldType, ParsedResponse, ResponseVariant, ResponseVariantKind, +}; -use crate::response_smax::{Resolved, Resolver, analyze_module_exports, scan_cascade_variants}; +use crate::response_smax::{ + Drops, Resolved, Resolver, analyze_module_exports, scan_cascade_variants, +}; use wa_transform::ModuleDefinition; /// Index of smax response parsers, keyed for request→response linkage. @@ -27,9 +31,27 @@ pub struct ResponseIndex { /// shapes, so an op whose response module ends differently (e.g. PingsClient's /// `…ResponseServerResponse`) needs a lookup that anchors on the known op name. in_slices: Vec<(String, String)>, + /// Constraints (literal values, reference paths, enum arguments) that were present + /// in a parser but not structurally resolvable, by reason. Surfaced under + /// `manifest.diagnostics.iq.dropsByReason` so "no constraint here" and "a constraint + /// we failed to extract" never look alike to a consumer. + /// + /// Shared with the resolvers this index builds later, so the request-anchored + /// fallback reports into it too — and therefore only meaningful once the whole scan + /// has run. [`crate::scan_iq_with_diagnostics`] snapshots it at the end, not here. + drops: Drops, } impl ResponseIndex { + /// See [`ResponseIndex::drops`]. Call after the scan; the fallback path adds to it. + pub(crate) fn drop_counts(&self) -> BTreeMap { + self.drops + .borrow() + .iter() + .map(|(reason, keys)| (reason.clone(), keys.len())) + .collect() + } + /// Look up the response for operation `x` (derived from a request module name). pub(crate) fn get_by_x(&self, x: &str) -> Option<&ParsedResponse> { self.by_x.get(x) @@ -46,7 +68,7 @@ impl ResponseIndex { .iter() .map(|(n, s)| (n.as_str(), s.as_str())) .collect(); - let resolver = Resolver::new(&slices); + let resolver = Resolver::with_drops(&slices, self.drops.clone()); let prefix = format!("WASmaxIn{x}Response"); for (name, slice) in &self.in_slices { let Some(variant) = name.strip_prefix(&prefix) else { @@ -55,15 +77,44 @@ impl ResponseIndex { // Skip the bare `…Response`, error variants, and mixin payloads. if variant.is_empty() || variant.contains("Mixin") - || variant_kind(variant) != ResponseVariantKind::Success + || variant_kind(variant, &[]) != ResponseVariantKind::Success { continue; } - if let Some(pr) = analyze_module_exports(slice, &resolver) - .into_iter() - .find(|(_, pr)| !pr.fields.is_empty()) - .map(|(_, pr)| pr) + // A parser with no fields is still a response: `makeResult({})` guarded by + // `type="result"` is a confirmation, and its assertions are the whole + // contract. Requiring a payload dropped those to a degraded `unknown`. + let exports = analyze_module_exports(slice, &resolver); + // The ROOT export, structurally: a child/helper parser's export name extends + // another export's at a word boundary (`parseFooResponseSuccess` vs + // `…SuccessPayload`), and its fields already nest in the root's tree. The + // same rule the incoming ack scan uses. + // + // Preferring "whichever has fields" picked the payload helper whenever the + // root was a fieldless confirmation — losing the root's assertions, which for + // a `makeResult({})` response ARE the whole contract. + let is_child = |name: &String| { + exports.iter().any(|(other, _)| { + other != name + && name + .strip_prefix(other.as_str()) + .is_some_and(|suffix| suffix.starts_with(char::is_uppercase)) + }) + }; + if let Some(pr) = exports + .iter() + .find(|(name, _)| !is_child(name)) + .or_else(|| exports.first()) + .map(|(_, pr)| pr.clone()) { + // The name gate above is a cheap pre-filter; this is the decision. WA's + // names contradict the wire discriminator often enough that + // `SetResponsePreKeySuccessVnameFailure` reads as a success while + // asserting `type="error"` — classifying on the suffix alone would hand + // an error parser back as the operation's single response shape. + if variant_kind(variant, &pr.assertions) != ResponseVariantKind::Success { + continue; + } return Some(pr); } } @@ -105,6 +156,7 @@ pub(crate) fn build_pass(defs: &[ModuleDefinition], source: &str) -> ResponseInd } let mut variants = Vec::new(); let mut primary: Vec = Vec::new(); + let mut primary_selected = false; for (tag, module, func) in variant_refs { // Resolve the exact parser the RPC calls (`o(module).`); a // `ResponseSuccess` module exports several `parse…` fns, so match by name. @@ -113,18 +165,41 @@ pub(crate) fn build_pass(defs: &[ModuleDefinition], source: &str) -> ResponseInd Some(Resolved::Union(v)) if !v.is_empty() => vec![union_field("value", v)], _ => Vec::new(), }; - let kind = variant_kind(&tag); - if kind == ResponseVariantKind::Success && primary.is_empty() { + let kind = variant_kind(&tag, &resolver.assertions(&module, &func)); + // Selection state, not payload emptiness. A first success variant with NO + // fields (a `makeResult({})` confirmation) left `primary` empty, so a later + // success variant overwrote it and `ParsedResponse.fields` contradicted the + // documented first-success rule. + if kind == ResponseVariantKind::Success && !primary_selected { primary = fields.clone(); + primary_selected = true; } // The variant's same-node discriminators (e.g. `type:"result"` / `type:"error"`), // recovered separately since the JS keeps them as parser asserts, not fields. // These let codegen guard each arm so the outcome union doesn't misclassify. let assertions = resolver.assertions(&module, &func); + // The per-RPC error vocabulary: which `` pairs THIS RPC's + // error arm accepts. It is a closed set and it differs per RPC, so it can + // only be read off the arm's own error arm. + // + // Gated on the variant kind, and not merely used to gate `error_class`: a + // SUCCESS payload can legitimately nest a union whose variant pins a `code` + // or `text` field for unrelated reasons (three PreKeys success variants do), + // and reporting that as an accepted error vocabulary contradicts the + // per-error-arm meaning documented on `ResponseVariant`. + let vocab = if kind.is_error() { + error_vocabulary(&fields) + } else { + ErrorVocabulary::default() + }; variants.push(ResponseVariant { tag, module_name: module, - kind, + // The side at fault is a property of the codes, so it is settled only + // once the vocabulary is read. + kind: vocab.refine(kind), + error_arms: vocab.arms, + error_envelope: vocab.envelope, assertions, fields, }); @@ -159,13 +234,257 @@ pub(crate) fn build_pass(defs: &[ModuleDefinition], source: &str) -> ResponseInd } // Keep the `WASmaxIn*` slices (owned) for the request-anchored fallback. - let in_slices: Vec<(String, String)> = slices + // SORTED. `slices` is a `HashMap`, so iterating it hands the fallback its candidates + // in a different order every run — and the fallback takes the first match. An op with + // two success-like `WASmaxInResponse*` modules would therefore attach a different + // response parser, and commit different IR, from one run to the next. Byte + // reproducibility is this repo's contract; nothing that feeds the artifact may depend + // on hash order. + let mut in_slices: Vec<(String, String)> = slices .iter() .filter(|(n, _)| n.starts_with("WASmaxIn")) .map(|(n, s)| (n.to_string(), s.to_string())) .collect(); + in_slices.sort_by(|a, b| a.0.cmp(&b.0)); + + ResponseIndex { + by_x, + in_slices, + drops: resolver.drops(), + } +} + +/// The `` codes/texts one response variant accepts, gathered from its error +/// disjunction. +#[derive(Default)] +struct ErrorVocabulary { + /// The accepted `(code, text)` shapes, in parser order. + arms: Vec, + /// Pins on the `` node enclosing the ones the arms discriminate, for a + /// two-level error. Recorded once rather than duplicated into every arm. + envelope: Option, +} + +impl ErrorVocabulary { + /// Refine `Error` into the side at fault: 4xx is the client's, 5xx the server's. + /// Derived from every code the variant accepts — arms and envelope alike — so a + /// variant that mixes families, or pins something outside both (the 207 partial + /// failure), stays a plain `Error` rather than being guessed into a side. + fn refine(&self, kind: ResponseVariantKind) -> ResponseVariantKind { + if kind != ResponseVariantKind::Error { + return kind; + } + let of = |c: i64| match c { + 400..=499 => Some(ResponseVariantKind::ClientError), + 500..=599 => Some(ResponseVariantKind::ServerError), + _ => None, + }; + let mut seen: Option = None; + for c in self + .arms + .iter() + .chain(self.envelope.as_ref()) + .flat_map(|a| [a.code, a.code_min, a.code_max]) + .flatten() + { + match (of(c), seen) { + (None, _) => return ResponseVariantKind::Error, + (Some(cur), None) => seen = Some(cur), + (Some(cur), Some(prev)) if cur == prev => {} + _ => return ResponseVariantKind::Error, + } + } + seen.unwrap_or(ResponseVariantKind::Error) + } +} - ResponseIndex { by_x, in_slices } +/// Collect the `` vocabulary from an error variant's resolved fields. +/// +/// The usual shape is an `errorXxxErrors` union field whose alternatives are the +/// per-namespace error mixins, each pinning its own `text`/`code` +/// (`literal(attrString, e, "text", "rate-overlimit")` + `literal(attrInt, e, "code", +/// 429)`), except the fallback arms, which range-check the code instead +/// (`attrIntRange(e, "code", 500, 599)`). +/// +/// But a good number of RPCs skip the disjunction and parse a single `` child +/// directly — `SetResponseConflict` pins `409`/`conflict` as plain nested fields, and +/// `GetAccessTokenAndSessionCookiesResponseTooManyAttempts` pins `431` the same way. So +/// the `code`/`text` reading is applied to EVERY traversed field, not only to fields +/// inside a `UnionVariant`; restricting it to unions silently emptied the vocabulary of +/// 29 error variants. Both forms are already carried on the fields (as `literal_value` / +/// `int_min`+`int_max`), so this reads them back rather than re-parsing the bundle. +fn error_vocabulary(fields: &[ParsedField]) -> ErrorVocabulary { + let mut v = ErrorVocabulary::default(); + let from_union = collect_error_arms(fields, &mut v.arms); + // Partition the variant's own (non-alternative) pins by the NODE they are read from. + // `SetResponsePreKeySuccessVnameFailure` pins `code=207` on `` and + // range-checks `code` 400..=599 on the `` inside it: folding both into + // one envelope tells a consumer that 207 must also fall in 400..=599, and leaves the + // inner range attached to nothing. The deepest pins belong to the node the arms + // discriminate and are merged into them; anything shallower is the envelope. + let mut by_path: std::collections::BTreeMap, ErrorArm> = Default::default(); + pins_by_path(fields, &[], &mut by_path); + if from_union && !by_path.is_empty() { + // The deepest pins sit on the node the arms discriminate; anything shallower + // encloses it. When every pin is at the variant's own node there IS no enclosing + // node — they are all shared constraints of the arms, and calling them an + // envelope would say the opposite of what the field documents. + let deepest = by_path.keys().map(Vec::len).max().unwrap_or(0); + let (inner, outer): (Vec<_>, Vec<_>) = by_path + .into_iter() + .partition(|(path, _)| path.len() == deepest); + // Shared constraints of the discriminating node: every arm is subject to them. + for (_, shared) in &inner { + for arm in &mut v.arms { + arm.code = arm.code.or(shared.code); + arm.text = arm.text.clone().or_else(|| shared.text.clone()); + arm.code_min = arm.code_min.or(shared.code_min); + arm.code_max = arm.code_max.or(shared.code_max); + } + } + let mut envelope = ErrorArm::default(); + for (_, outer_pins) in outer { + envelope.code = envelope.code.or(outer_pins.code); + envelope.text = envelope.text.or(outer_pins.text); + envelope.code_min = envelope.code_min.or(outer_pins.code_min); + envelope.code_max = envelope.code_max.or(outer_pins.code_max); + } + if envelope != ErrorArm::default() { + v.envelope = Some(envelope); + } + } + v +} + +/// The `code`/`text` pins of the variant's own fields, grouped by the node path they are +/// read from. Disjunction alternatives are skipped — each of those is its own arm. +fn pins_by_path( + fields: &[ParsedField], + base: &[String], + out: &mut std::collections::BTreeMap, ErrorArm>, +) { + for f in fields { + let mut path = base.to_vec(); + path.extend(f.source_path.iter().flatten().cloned()); + match (f.wire_name.as_deref().unwrap_or(&f.name), &f.literal_value) { + ("code", Some(lit)) => { + if let Ok(code) = lit.parse::() { + out.entry(path.clone()).or_default().code = Some(code); + } + } + ("text", Some(lit)) => { + out.entry(path.clone()).or_default().text = Some(lit.clone()); + } + ("code", None) => { + if let (Some(min), Some(max)) = (f.int_min, f.int_max) { + let e = out.entry(path.clone()).or_default(); + e.code_min = Some(min); + e.code_max = Some(max); + } + } + _ => {} + } + if let Some(children) = &f.children { + pins_by_path(children, &path, out); + } + } +} + +/// One arm per accepted `` shape, so the `(code, text)` pairing survives. +/// +/// A `…Errors` disjunction contributes one arm per alternative; an RPC that parses a +/// single `` child directly contributes exactly one unnamed arm. Flattening these +/// into two independent lists would let an emitter combine one arm's code with another's +/// text — `400 feature-not-implemented` matches no branch and is unparseable, which is +/// the whole failure class this domain exists to prevent. +fn collect_error_arms(fields: &[ParsedField], out: &mut Vec) -> bool { + let mut found_union = false; + collect_union_arms(fields, out, &mut found_union); + if !found_union { + // No disjunction: the variant parses one `` shape, so its pins are one arm. + // An arm with NO pins is still information when the parser reads `code`/`text` at + // all — it says "one accepted shape, unconstrained", which is a different claim + // from "no vocabulary extracted". `CreateCustomPaymentMethodResponseIQErrorWithCodeAndReason` + // and `RemoveCustomPaymentMethodResponseError` are that shape, and dropping their + // arm made an unrestricted error indistinguishable from a failed extraction. + let arm = arm_pins(fields); + if arm != ErrorArm::default() || reads_error_fields(fields) { + out.push(arm); + } + } + found_union +} + +/// Walk the tree for disjunction alternatives, pushing one arm per leaf alternative. +fn collect_union_arms(fields: &[ParsedField], out: &mut Vec, found: &mut bool) { + for f in fields { + for uv in f.union_variants.iter().flatten() { + *found = true; + // What THIS alternative pins itself, before descending. An alternative can + // both pin `429`/`rate-overlimit` and carry a further payload union of + // reasons (`CreateOrAddGroupRateLimitError` does), and the nested reasons pin + // nothing — so replacing the outer arm with them would publish two arms with + // no usable pairing and drop the shape the server actually sends. + let own = arm_pins(&uv.fields); + let before = out.len(); + let mut nested = false; + collect_union_arms(&uv.fields, out, &mut nested); + if nested { + for a in &mut out[before..] { + // Inner names are the specific ones; the outer pins are inherited + // wherever the inner arm has none of its own. + a.name.get_or_insert_with(|| uv.name.clone()); + a.code = a.code.or(own.code); + a.text = a.text.clone().or_else(|| own.text.clone()); + a.code_min = a.code_min.or(own.code_min); + a.code_max = a.code_max.or(own.code_max); + } + } else { + let mut arm = own; + arm.name = Some(uv.name.clone()); + out.push(arm); + } + } + if let Some(children) = &f.children { + collect_union_arms(children, out, found); + } + } +} + +/// Whether the parser reads an `` `code`/`text` at all, pinned or not. +fn reads_error_fields(fields: &[ParsedField]) -> bool { + fields.iter().any(|f| { + matches!(f.wire_name.as_deref().unwrap_or(&f.name), "code" | "text") + || f.children.as_deref().is_some_and(reads_error_fields) + }) +} + +/// The `code`/`text` pins of one error shape, scanning its whole field subtree but not +/// descending into disjunction alternatives (each of those is its own arm). +fn arm_pins(fields: &[ParsedField]) -> ErrorArm { + let mut arm = ErrorArm::default(); + fn walk(fields: &[ParsedField], arm: &mut ErrorArm) { + for f in fields { + match (f.wire_name.as_deref().unwrap_or(&f.name), &f.literal_value) { + ("code", Some(lit)) => arm.code = lit.parse::().ok().or(arm.code), + ("text", Some(lit)) => arm.text = Some(lit.clone()), + // A fallback arm accepts any text within a code RANGE (400–499 / + // 500–599), which no enumeration of exact codes can express. + ("code", None) => { + if let (Some(min), Some(max)) = (f.int_min, f.int_max) { + arm.code_min = Some(min); + arm.code_max = Some(max); + } + } + _ => {} + } + if let Some(children) = &f.children { + walk(children, arm); + } + } + } + walk(fields, &mut arm); + arm } /// A discriminated-union field carrying `variants`. @@ -188,8 +507,48 @@ fn rpc_op_name(module: &str) -> String { .to_string() } -/// Classify a response variant by its discriminator tag's tokens. -fn variant_kind(tag: &str) -> ResponseVariantKind { +/// Classify a response variant: by what its parser asserts on the wire first, then by +/// its discriminator tag's tokens. +/// +/// The root discriminator wins because it is the protocol talking rather than a naming +/// convention. `SetResponsePreKeySuccessVnameFailure` reads as a success by every token +/// in its name, yet it asserts `type="error"` and parses an `` — the +/// prekeys landed, the vname did not, and the server said so with an error stanza. +/// Judging it by the tag alone classified a wire error as a success and, since the error +/// vocabulary is gated on the kind, silently dropped the codes and texts it accepts. +fn variant_kind(tag: &str, assertions: &[wa_ir::ResponseAssertion]) -> ResponseVariantKind { + let asserts_error = assertions.iter().any(|a| { + a.kind == wa_ir::AssertionKind::Attr + && a.name.as_deref() == Some("type") + && a.value.as_deref() == Some("error") + }); + if asserts_error { + return ResponseVariantKind::Error; + } + // `type="result"` is the wire saying this arrived on the SUCCESS channel, and the + // discriminator outranks the name — the whole point of taking the root assertion + // first. Only `type="error"` was honoured, so `CreateResponseGroupAlreadyExists` and + // `RequestSilentNonceResponseRecoveryRequired` shipped as `kind: "error"` while + // asserting `type: "result"`, telling a consumer to route them opposite to the wire. + // + // An error-ish NAME on a `result` still means something: it is a structured + // non-happy outcome, not an ordinary success. That is what `Alternative` is for. + let asserts_result = assertions.iter().any(|a| { + a.kind == wa_ir::AssertionKind::Attr + && a.name.as_deref() == Some("type") + && a.value.as_deref() == Some("result") + }); + if asserts_result { + return match variant_kind_by_tag(tag) { + ResponseVariantKind::Success => ResponseVariantKind::Success, + _ => ResponseVariantKind::Alternative, + }; + } + variant_kind_by_tag(tag) +} + +/// The name-token fallback, for a variant whose parser pins no `type`. +fn variant_kind_by_tag(tag: &str) -> ResponseVariantKind { const ERROR_TOKENS: &[&str] = &[ "Error", "InvalidRequest", @@ -227,6 +586,38 @@ fn response_op_name(module: &str) -> String { mod tests { use super::*; + fn attr(name: &str, value: &str) -> wa_ir::ResponseAssertion { + wa_ir::ResponseAssertion { + kind: wa_ir::AssertionKind::Attr, + name: Some(name.to_string()), + value: Some(value.to_string()), + reference_path: None, + } + } + + #[test] + fn an_asserted_result_outranks_an_error_name_token() { + // `CreateResponseGroupAlreadyExists` asserts `type="result"`: the wire says it + // arrived on the success channel, and the discriminator outranks the name. Only + // `type="error"` was honoured, so these shipped as `kind: "error"` and told a + // consumer to route them opposite to the wire. + let a = [attr("type", "result")]; + assert_eq!( + variant_kind("CreateResponseGroupAlreadyExists", &a), + ResponseVariantKind::Alternative, + "an error-ish name on a `result` is a structured non-happy outcome" + ); + assert_eq!( + variant_kind("CreateResponseSuccess", &a), + ResponseVariantKind::Success + ); + // The error discriminator still wins outright. + assert_eq!( + variant_kind("CreateResponseSuccess", &[attr("type", "error")]), + ResponseVariantKind::Error + ); + } + #[test] fn op_name_strips_prefix_suffix() { assert_eq!( @@ -253,6 +644,267 @@ mod tests { assert_eq!(pr.fields[0].name, "id"); } + /// A minimal RPC with one client-error arm over two error mixins, plus the + /// open-ended server fallback — the shape every namespace repeats. + const ERROR_RPC: &str = r#" + __d("WASmaxInFooIQErrorBadRequestMixin",["WASmaxParseUtils"],(function(t,n,r,o,a,i,l){ + function e(e){ + var t = o("WASmaxParseUtils").assertTag(e, "error"); if(!t.success) return t; + var n = o("WASmaxParseUtils").literal(o("WASmaxParseUtils").attrString, e, "text", "bad-request"); if(!n.success) return n; + var r = o("WASmaxParseUtils").literal(o("WASmaxParseUtils").attrInt, e, "code", 400); + return r.success ? o("WAResultOrError").makeResult({text:n.value,code:r.value}) : r; + } + l.parseIQErrorBadRequestMixin = e; + }), 98); + __d("WASmaxInFooIQErrorFallbackServerMixin",["WASmaxParseUtils"],(function(t,n,r,o,a,i,l){ + function e(e){ + var t = o("WASmaxParseUtils").assertTag(e, "error"); if(!t.success) return t; + var n = o("WASmaxParseUtils").attrString(e, "text"); if(!n.success) return n; + var r = o("WASmaxParseUtils").attrIntRange(e, "code", 500, 599); + return r.success ? o("WAResultOrError").makeResult({text:n.value,code:r.value}) : r; + } + l.parseIQErrorFallbackServerMixin = e; + }), 98); + __d("WASmaxInFooClientErrors",["WASmaxParseUtils"],(function(t,n,r,o,a,i,l){ + function e(e){ + var t = o("WASmaxInFooIQErrorBadRequestMixin").parseIQErrorBadRequestMixin(e); + if(t.success) return o("WAResultOrError").makeResult({name:"IQErrorBadRequest",value:t.value}); + return o("WASmaxParseUtils").errorMixinDisjunction(e,["IQErrorBadRequest"],[t]); + } + l.parseClientErrors = e; + }), 98); + __d("WASmaxInFooServerErrors",["WASmaxParseUtils"],(function(t,n,r,o,a,i,l){ + function e(e){ + var t = o("WASmaxInFooIQErrorFallbackServerMixin").parseIQErrorFallbackServerMixin(e); + if(t.success) return o("WAResultOrError").makeResult({name:"IQErrorFallbackServer",value:t.value}); + return o("WASmaxParseUtils").errorMixinDisjunction(e,["IQErrorFallbackServer"],[t]); + } + l.parseServerErrors = e; + }), 98); + __d("WASmaxInFooGetBarResponseSuccess",["WASmaxParseUtils"],(function(t,n,r,o,a,i,l){ + function e(e,t){ + var n = o("WASmaxParseUtils").assertTag(e, "iq"); if(!n.success) return n; + var s = o("WASmaxParseUtils").literal(o("WASmaxParseUtils").attrString, e, "type", "result"); + return s.success ? o("WAResultOrError").makeResult({type:s.value}) : s; + } + l.parseGetBarResponseSuccess = e; + }), 98); + __d("WASmaxInFooGetBarResponseClientError",["WASmaxParseUtils"],(function(t,n,r,o,a,i,l){ + function e(e,t){ + var n = o("WASmaxParseUtils").assertTag(e, "iq"); if(!n.success) return n; + var r = o("WASmaxParseUtils").flattenedChildWithTag(e, "error"); if(!r.success) return r; + var i = o("WASmaxInFooClientErrors").parseClientErrors(r.value); + return i.success ? o("WAResultOrError").makeResult({errorClientErrors:i.value}) : i; + } + l.parseGetBarResponseClientError = e; + }), 98); + __d("WASmaxInFooGetBarResponseServerError",["WASmaxParseUtils"],(function(t,n,r,o,a,i,l){ + function e(e,t){ + var n = o("WASmaxParseUtils").assertTag(e, "iq"); if(!n.success) return n; + var r = o("WASmaxParseUtils").flattenedChildWithTag(e, "error"); if(!r.success) return r; + var i = o("WASmaxInFooServerErrors").parseServerErrors(r.value); + return i.success ? o("WAResultOrError").makeResult({errorServerErrors:i.value}) : i; + } + l.parseGetBarResponseServerError = e; + }), 98); + __d("WASmaxFooGetBarRPC",["WASmaxParseUtils"],(function(t,n,r,o,a,i,l){ + function e(e,t){ + var n = o("WASmaxInFooGetBarResponseSuccess").parseGetBarResponseSuccess(e,t); + if(n.success) return o("WAResultOrError").makeResult({name:"GetBarResponseSuccess",value:n.value}); + var r = o("WASmaxInFooGetBarResponseClientError").parseGetBarResponseClientError(e,t); + if(r.success) return o("WAResultOrError").makeResult({name:"GetBarResponseClientError",value:r.value}); + var a = o("WASmaxInFooGetBarResponseServerError").parseGetBarResponseServerError(e,t); + return a.success ? o("WAResultOrError").makeResult({name:"GetBarResponseServerError",value:a.value}) : a; + } + l.default = e; + }), 98);"#; + + #[test] + fn variant_carries_its_closed_error_vocabulary() { + let defs = wa_transform::extract_module_definitions(ERROR_RPC); + let idx = build_pass(&defs, ERROR_RPC); + let pr = idx.get_by_x("FooGetBar").expect("indexed by X"); + let v = |tag: &str| { + pr.variants + .iter() + .find(|v| v.tag == tag) + .unwrap_or_else(|| panic!("no variant {tag}")) + }; + // A success variant carries no error vocabulary. + let ok = v("GetBarResponseSuccess"); + assert_eq!(ok.kind, ResponseVariantKind::Success); + assert!(ok.error_arms.is_empty() && ok.error_envelope.is_none()); + // The client arm's vocabulary is CLOSED: exactly what its disjunction accepts. + // Answering `404 item-not-found` here matches no branch — the bug this exists + // to make visible — so 404 must not appear. + let ce = v("GetBarResponseClientError"); + assert_eq!(ce.kind, ResponseVariantKind::ClientError); + assert_eq!(ce.error_arms.len(), 1); + assert_eq!( + (ce.error_arms[0].code, ce.error_arms[0].text.as_deref()), + (Some(400), Some("bad-request")) + ); + // The server arm is the open-ended fallback: any text, any code in 500..=599. + let se = v("GetBarResponseServerError"); + assert_eq!(se.kind, ResponseVariantKind::ServerError); + assert_eq!(se.error_arms.len(), 1); + assert_eq!(se.error_arms[0].code, None, "a range is not an exact code"); + assert_eq!( + (se.error_arms[0].code_min, se.error_arms[0].code_max), + (Some(500), Some(599)) + ); + } + + #[test] + fn error_arms_keep_code_and_text_paired() { + // The flattened lists cannot say which code goes with which text: an arm taking + // 400/bad-request and 429/rate-overlimit flattens to two codes and two texts, + // and nothing then rules out `400 rate-overlimit` — a combination the parser + // rejects. An emitter picking one value from each list would produce exactly the + // unparseable stanza this domain exists to prevent, so the pairing is carried. + let defs = wa_transform::extract_module_definitions(ERROR_RPC); + let idx = build_pass(&defs, ERROR_RPC); + let pr = idx.get_by_x("FooGetBar").expect("indexed by X"); + let v = |tag: &str| pr.variants.iter().find(|v| v.tag == tag).expect(tag); + + let ce = v("GetBarResponseClientError"); + assert_eq!(ce.error_arms.len(), 1); + let arm = &ce.error_arms[0]; + assert_eq!(arm.name.as_deref(), Some("IQErrorBadRequest")); + assert_eq!( + (arm.code, arm.text.as_deref()), + (Some(400), Some("bad-request")) + ); + + // A fallback arm pins a range and NO text: it accepts any text in 500..=599, so + // a `text` of `None` there is the fact, not a gap. + let se = v("GetBarResponseServerError"); + assert_eq!(se.error_arms.len(), 1); + let fb = &se.error_arms[0]; + assert_eq!(fb.name.as_deref(), Some("IQErrorFallbackServer")); + assert_eq!(fb.code, None); + assert_eq!(fb.text, None); + assert_eq!((fb.code_min, fb.code_max), (Some(500), Some(599))); + + // A success variant carries no arms at all. + assert!(v("GetBarResponseSuccess").error_arms.is_empty()); + } + + #[test] + fn a_nested_payload_union_inherits_the_outer_error_pins() { + // An alternative can BOTH pin a code/text and carry a further payload union of + // reasons that pin nothing (`CreateOrAddGroupRateLimitError` does). Replacing the + // outer arm with the nested reasons publishes arms with no usable pairing and + // drops the shape the server actually sends, so the outer pins are inherited. + let bundle = ERROR_RPC.replace( + r#"__d("WASmaxInFooClientErrors",["WASmaxParseUtils"],(function(t,n,r,o,a,i,l){ + function e(e){ + var t = o("WASmaxInFooIQErrorBadRequestMixin").parseIQErrorBadRequestMixin(e); + if(t.success) return o("WAResultOrError").makeResult({name:"IQErrorBadRequest",value:t.value}); + return o("WASmaxParseUtils").errorMixinDisjunction(e,["IQErrorBadRequest"],[t]); + } + l.parseClientErrors = e; + }), 98);"#, + r#"__d("WASmaxInFooTimeRateLimitMixin",["WASmaxParseUtils"],(function(t,n,r,o,a,i,l){ + function e(e){ + var t = o("WASmaxParseUtils").assertTag(e, "error"); if(!t.success) return t; + var n = o("WASmaxParseUtils").attrString(e, "reason"); + return n.success ? o("WAResultOrError").makeResult({reason:n.value}) : n; + } + l.parseTimeRateLimitMixin = e; + }), 98); + __d("WASmaxInFooReasons",["WASmaxParseUtils"],(function(t,n,r,o,a,i,l){ + function e(e){ + var t = o("WASmaxInFooTimeRateLimitMixin").parseTimeRateLimitMixin(e); + if(t.success) return o("WAResultOrError").makeResult({name:"TimeRateLimit",value:t.value}); + return o("WASmaxParseUtils").errorMixinDisjunction(e,["TimeRateLimit"],[t]); + } + l.parseReasons = e; + }), 98); + __d("WASmaxInFooRateLimitMixin",["WASmaxParseUtils"],(function(t,n,r,o,a,i,l){ + function e(e){ + var t = o("WASmaxParseUtils").assertTag(e, "error"); if(!t.success) return t; + var n = o("WASmaxParseUtils").literal(o("WASmaxParseUtils").attrString, e, "text", "rate-overlimit"); if(!n.success) return n; + var r = o("WASmaxParseUtils").literal(o("WASmaxParseUtils").attrInt, e, "code", 429); if(!r.success) return r; + var q = o("WASmaxInFooReasons").parseReasons(e); + return q.success ? o("WAResultOrError").makeResult({text:n.value,code:r.value,reason:q.value}) : q; + } + l.parseRateLimitMixin = e; + }), 98); + __d("WASmaxInFooClientErrors",["WASmaxParseUtils"],(function(t,n,r,o,a,i,l){ + function e(e){ + var t = o("WASmaxInFooRateLimitMixin").parseRateLimitMixin(e); + if(t.success) return o("WAResultOrError").makeResult({name:"RateLimitError",value:t.value}); + return o("WASmaxParseUtils").errorMixinDisjunction(e,["RateLimitError"],[t]); + } + l.parseClientErrors = e; + }), 98);"#, + ); + let defs = wa_transform::extract_module_definitions(&bundle); + let idx = build_pass(&defs, &bundle); + let pr = idx.get_by_x("FooGetBar").expect("indexed by X"); + let ce = pr + .variants + .iter() + .find(|v| v.tag == "GetBarResponseClientError") + .expect("client error"); + assert!( + !ce.error_arms.is_empty(), + "the nested union must not erase the arm" + ); + for arm in &ce.error_arms { + assert_eq!( + (arm.code, arm.text.as_deref()), + (Some(429), Some("rate-overlimit")), + "every nested reason keeps the outer pins: {arm:?}" + ); + } + // The specific inner name wins over the outer one. + assert_eq!(ce.error_arms[0].name.as_deref(), Some("TimeRateLimit")); + } + + #[test] + fn the_error_side_is_derived_from_codes_not_from_the_variant_name() { + // The codes decide, so `…ResponseInternalServerError` (which reads like a server + // arm but is spelled inconsistently across namespaces) cannot be misfiled, and a + // variant whose codes settle nothing stays a plain `Error` rather than a guess. + let arm = |code: Option, min: Option, max: Option| ErrorArm { + code, + code_min: min, + code_max: max, + ..Default::default() + }; + let vocab = |arms: Vec| ErrorVocabulary { + arms, + envelope: None, + }; + let refine = |arms: Vec| vocab(arms).refine(ResponseVariantKind::Error); + + assert_eq!( + refine(vec![arm(Some(400), None, None), arm(Some(429), None, None)]), + ResponseVariantKind::ClientError + ); + assert_eq!( + refine(vec![arm(None, Some(500), Some(599))]), + ResponseVariantKind::ServerError + ); + // Mixed families, or a code outside both, is not classified — never guessed. + assert_eq!( + refine(vec![arm(Some(400), None, None), arm(Some(500), None, None)]), + ResponseVariantKind::Error + ); + assert_eq!( + refine(vec![arm(Some(207), None, None)]), + ResponseVariantKind::Error + ); + assert_eq!(refine(vec![]), ResponseVariantKind::Error); + // A success variant is never touched. + assert_eq!( + vocab(vec![arm(Some(400), None, None)]).refine(ResponseVariantKind::Success), + ResponseVariantKind::Success + ); + } + #[test] fn build_pass_recovers_nested_child_response() { // A ResponseSuccess whose payload is a child parsed by a local fn — the diff --git a/crates/wa-scan/src/response_smax.rs b/crates/wa-scan/src/response_smax.rs index acad31b..4f6f12a 100644 --- a/crates/wa-scan/src/response_smax.rs +++ b/crates/wa-scan/src/response_smax.rs @@ -33,17 +33,27 @@ //! to avoid any regression to its 33 stanzas / tests. use std::cell::RefCell; -use std::collections::{HashMap, HashSet}; +use std::collections::{BTreeMap, HashMap, HashSet}; use oxc_allocator::Allocator; use oxc_ast::ast::{Argument, CallExpression, Expression, Function, Statement}; use oxc_span::GetSpan; use wa_ir::wap; use wa_ir::{ - AssertionKind, ParsedField, ParsedFieldType, ParsedResponse, ResponseAssertion, UnionVariant, + AssertionKind, AttrEnumRef, AttrEnumVariant, ParsedField, ParsedFieldType, ParsedResponse, + ResponseAssertion, Scalar, UnionVariant, }; -use wa_oxc::{arg_expr, as_call, as_identifier, as_int, as_string_lit, callee_method}; +use wa_oxc::{ + arg_expr, as_call, as_identifier, as_int, as_string_lit, callee_method, callee_object, +}; + +/// Drop reason for an enum accessor whose enum could not be resolved to its variants. +pub(crate) const ENUM_DROP: &str = "response enum argument not structurally resolvable"; + +/// The `dropsByReason` key for a `contentLiteralBytes` pin whose sequence is not a +/// compile-time constant. +const BYTES_DROP: &str = "contentLiteralBytes sequence not statically resolvable"; /// A module's local parser functions, keyed by name → re-parsable source. Child /// accessors reference these by identifier (`optionalChildWithTag(n, "x", parseX)`). @@ -73,8 +83,28 @@ pub(crate) struct Resolver<'a> { /// holds fields/unions); see [`Resolver::assertions`]. assert_cache: RefCell>>, assert_in_progress: RefCell>, + /// Memoized `(module, enum)` → resolved wire enum, for the enum argument of an + /// `attrStringEnum`/`contentStringEnum` accessor; see [`Resolver::resolve_enum`]. + enum_cache: RefCell>>, + /// Constraints seen but **not** structurally resolvable: reason → the set of + /// distinct constraints lost under it. Surfaced (as set sizes) under + /// `manifest.diagnostics.iq.dropsByReason` so a consumer can tell "this field carries + /// no constraint" from "a constraint was there and we failed to extract it". + /// + /// Keyed rather than counted because the same parser source is analyzed more than + /// once — `resolve` walks it for fields and `assertions` walks it again for + /// discriminators, and a module can be reached from several RPCs. A raw counter would + /// therefore report one lost enum several times, which says nothing about how much + /// data is actually missing. The unit is **distinct constraints**. + drops: Drops, } +/// The shared drop collector: reason → the distinct constraints lost under it. Shared +/// (rather than owned) so a resolver built later — the request-anchored fallback in +/// [`crate::response_index`] — reports into the same place instead of dropping its +/// findings on the floor. +pub(crate) type Drops = std::rc::Rc>>>; + impl<'a> Resolver<'a> { pub(crate) fn new(slices: &'a HashMap<&'a str, &'a str>) -> Self { Resolver { @@ -83,7 +113,93 @@ impl<'a> Resolver<'a> { in_progress: RefCell::new(HashSet::new()), assert_cache: RefCell::new(HashMap::new()), assert_in_progress: RefCell::new(HashSet::new()), + enum_cache: RefCell::new(HashMap::new()), + drops: Drops::default(), + } + } + + /// The drops this resolver alone recorded, as counts. + /// + /// The IQ path reads the shared collector through + /// [`crate::response_index::ResponseIndex`] instead, since its fallback resolver + /// reports into the same place. The incoming ack pass owns its resolver outright and + /// reads it here — those drops were simply discarded before. + pub(crate) fn drop_counts(&self) -> BTreeMap { + self.drops + .borrow() + .iter() + .map(|(reason, keys)| (reason.clone(), keys.len())) + .collect() + } + + /// A resolver that reports its drops into an existing collector. + pub(crate) fn with_drops(slices: &'a HashMap<&'a str, &'a str>, drops: Drops) -> Self { + Self { + drops, + ..Self::new(slices) + } + } + + /// The shared collector, for a caller that needs to read it after further scanning. + pub(crate) fn drops(&self) -> Drops { + self.drops.clone() + } + + /// Record one unresolvable constraint under `reason`, identified by `key` so the + /// same loss seen again on a second analysis pass is not counted twice. + fn drop_note_keyed(&self, reason: &str, key: String) { + self.drops + .borrow_mut() + .entry(reason.to_string()) + .or_default() + .insert(key); + } + + /// Resolve the enum argument of an enum accessor (`o("WASmaxInFooEnums").ENUM_OFF_ON`) + /// to its full `(name, module, variants)`. Reuses [`wa_enums::resolve_named_enum`], the + /// same resolver the request side uses, so both halves of the protocol type an enum + /// attribute identically. `None` — never a guess — when the module isn't in the bundle, + /// the export isn't a resolvable enum, or any variant value isn't a string (every + /// stanza-attr enum is a wire-token enum). + fn resolve_enum(&self, module: &str, name: &str, occurrence: &str) -> Option { + let key = (module.to_string(), name.to_string()); + // Count per OCCURRENCE, not per distinct enum: `dropsByReason` measures how much + // constraint data was lost, and every other reason here is per-occurrence. A + // memoized miss must therefore still be counted, so N fields validating against + // the same unresolvable enum report N losses rather than one. + if let Some(hit) = self.enum_cache.borrow().get(&key) { + if hit.is_none() { + self.drop_note_keyed(ENUM_DROP, format!("{module}.{name}@{occurrence}")); + } + return hit.clone(); + } + let resolved = self + .slices + .get(module) + .and_then(|slice| wa_enums::resolve_named_enum(slice, module, name)) + .and_then(|def| { + let variants: Vec = def + .variants + .into_iter() + .map(|v| match v.value { + Scalar::Str(s) => Some(AttrEnumVariant { + name: v.name, + value: s, + }), + _ => None, + }) + .collect::>>()?; + (!variants.is_empty()).then(|| AttrEnumRef { + name: name.to_string(), + module: module.to_string(), + variants, + }) + }); + if resolved.is_none() { + self.drop_note_keyed(ENUM_DROP, format!("{module}.{name}@{occurrence}")); } + self.enum_cache.borrow_mut().insert(key, resolved.clone()); + resolved } /// Resolve `o(module).func(…)` to its fields or union, or `None` if the module @@ -205,6 +321,28 @@ enum Binding { /// `flattenedChildWithTag` descent (`attrString(n.value, "id")` reads off the /// `` child `n`, not the parent node). source_path: Option>, + /// The fixed value a `literal`/`optionalLiteral` wrapper pins this accessor to + /// (`literal(attrString, e, "type", "admin")` → `"admin"`), stringified. + literal_value: Option, + /// The wire enum the accessor validates the value against, for + /// `attrStringEnum`/`contentStringEnum`. + enum_ref: Option, + /// The request path an `optionalLiteral(…, ref.value)` echo pins the value to. + /// Its required twin is recorded as a `Reference` assertion instead (an optional + /// pin guards nothing, so it is not an assertion). + reference_path: Option>, + }, + /// A value read off the **request** rather than the response node — + /// `o("WASmaxParseReference").attrStringFromReference(request, ["to"])`. `path` is + /// the helper's path argument (wrappers to descend, then the attribute name). The + /// binding doubles as a [`Binding::Field`]: a reference var is usually consumed only + /// by a `literal(…, ref.value)` echo guard, but when the tail names it, it is a real + /// output field whose value happens to come from the request. + Reference { + path: Vec, + method: String, + field_type: ParsedFieldType, + required: bool, }, /// A cross-module parser call (`o(mod).parse(node)`) that resolved to a /// flat field list: a same-node payload mixin or a plain sub-parser. @@ -286,7 +424,22 @@ fn analyze_fn_source( Statement::FunctionDeclaration(f) => Some(&**f), _ => None, })?; - analyze_function(func, locals, resolver, visited) + analyze_function(func, locals, resolver, visited, &parser_site(fn_source)) +} + +/// A stable identity for one parser body, for keying diagnostics per SITE. +/// +/// The source itself, hashed: two parsers validating the same attribute against the same +/// unresolvable enum are two lost constraints, and keying on `(enum, attribute)` alone +/// collapsed them — so removing one moved no counter. Hashing the body rather than +/// threading a module/function name keeps the key stable across the two analysis passes +/// (`resolve` for fields, `assertions` for discriminators re-walk the identical source) +/// without carrying context through every frame. +fn parser_site(fn_source: &str) -> String { + use std::hash::{Hash, Hasher}; + let mut h = std::collections::hash_map::DefaultHasher::new(); + fn_source.hash(&mut h); + format!("{:016x}", h.finish()) } fn analyze_function( @@ -294,8 +447,24 @@ fn analyze_function( locals: &LocalFns, resolver: &Resolver, visited: &mut HashSet, + site: &str, ) -> Option<(Vec, Vec)> { let body = func.body.as_ref()?; + // A response parser's signature is `parse…(node, reference)`: the second parameter + // is the REQUEST the answer is correlated against. Every echo rule is relative to + // it, so it is threaded down and a `…FromReference` call on any other node is + // rejected rather than silently reported as "the request" (see [`classify_reference`]). + let reference_param = func + .params + .items + .get(1) + .and_then(|p| p.pattern.get_identifier_name()); + let ctx = FnCtx { + locals, + resolver, + reference_param: reference_param.as_deref(), + site, + }; // Same-node cross-module mixins bubble their discriminators up by default (so an // error variant inherits the `type:"error"` its mixin asserts). But a mixin whose // result the tail consumes *optionally* (`X.success ? X.value : null`) does not @@ -326,8 +495,7 @@ fn analyze_function( let b = classify_call( init, &mut assertions, - locals, - resolver, + &ctx, visited, &bindings, suppressed.contains(name.as_str()), @@ -349,19 +517,37 @@ fn analyze_function( Some((assertions, fields)) } +/// The immutable context one parse function is analyzed under: its module's local +/// parsers, the cross-module resolver, and the name of its `reference` parameter. +/// Grouped so the per-binding classifier keeps a readable signature. +struct FnCtx<'c> { + locals: &'c LocalFns, + resolver: &'c Resolver<'c>, + /// The parser's `reference` parameter — the request an echo rule is relative to. + reference_param: Option<&'c str>, + /// This parser body's identity, so a dropped constraint is counted per site rather + /// than per constraint name — see [`parser_site`]. + site: &'c str, +} + /// Classify the RHS of a railway binding into a [`Binding`], recording any /// assertion it implies (assertTag/assertAttr/literal…). fn classify_call( init: &Expression, assertions: &mut Vec, - locals: &LocalFns, - resolver: &Resolver, + ctx: &FnCtx, visited: &mut HashSet, bindings: &HashMap, // Whether this binding's var is consumed optionally by the tail, so a same-node // mixin it binds must not bubble its discriminators (see `analyze_function`). suppress_bubble: bool, ) -> Binding { + let FnCtx { + resolver, + reference_param, + site, + .. + } = *ctx; let Some(call) = as_call(init) else { return Binding::None; }; @@ -425,6 +611,7 @@ fn classify_call( kind: AssertionKind::Tag, name: Some(tag.to_string()), value: None, + reference_path: None, }); } Binding::None @@ -436,6 +623,7 @@ fn classify_call( kind: AssertionKind::Attr, name: name.map(str::to_string), value: value.map(str::to_string), + reference_path: None, }); Binding::None } @@ -445,19 +633,51 @@ fn classify_call( // wrapped accessor; when it's only an assertion (unreferenced) it emits // nothing. `literalContent` pins a constant string (no makeResult value). "literal" => { - // `literal(ACC, node, "attr", "fixedValue")` pins the attr to a constant — - // a hard discriminator when the value is a string literal on the SAME node - // (`type:"result"`). A reference value (`literal(…, "id", r.value)`) is - // request-relative, not a fixed discriminator, so skip it. - if source_path.is_none() - && let Some(attr) = args.get(2).and_then(arg_expr).and_then(as_string_lit) - && let Some(value) = args.get(3).and_then(arg_expr).and_then(as_string_lit) - { - assertions.push(ResponseAssertion { - kind: AssertionKind::Attr, - name: Some(attr.to_string()), - value: Some(value.to_string()), - }); + // The pinned value is one of three things: + // - a compile-time literal (`"result"`, `429`) → a hard discriminator, and + // the value the field carries; + // - a value read from the REQUEST (`r.value` where `r` came from + // `attrStringFromReference(request, ["to"])`) → an *echo* rule: the attr + // must equal that request field, which is not a constant but is every bit + // as binding on an emitter; + // - anything else → not statically resolvable; counted, never guessed. + let attr = args.get(2).and_then(arg_expr).and_then(as_string_lit); + let literal_value = args.get(3).and_then(arg_expr).and_then(static_literal); + let reference_path = args + .get(3) + .and_then(arg_expr) + .and_then(|e| reference_path_of(e, bindings)); + // The ASSERTION is root-relative, so it is only emitted for a pin on the + // parser's own node. The DROP is not: a nested pin we could not resolve is a + // constraint lost just the same, and suppressing its report along with the + // assertion would leave the field with no pin while `dropsByReason` + // simultaneously claimed nothing had gone missing. + if let Some(attr) = attr { + match (&literal_value, &reference_path) { + (Some(value), _) if source_path.is_none() => { + assertions.push(ResponseAssertion { + kind: AssertionKind::Attr, + name: Some(attr.to_string()), + value: Some(value.clone()), + reference_path: None, + }) + } + (None, Some(path)) if source_path.is_none() => { + assertions.push(ResponseAssertion { + kind: AssertionKind::Reference, + name: Some(attr.to_string()), + value: None, + reference_path: Some(path.clone()), + }) + } + (None, None) => resolver.drop_note_keyed( + "literal attr value not statically resolvable", + format!("{site}:{attr}"), + ), + // A resolved pin on a descended node: carried on the field below, + // where it belongs, rather than as a root assertion. + _ => {} + } } let inner = args .first() @@ -473,6 +693,13 @@ fn classify_call( int_range: None, wire_name, source_path, + literal_value, + enum_ref: None, + // A `literal` on a DESCENDED node records no root assertion (the + // assertion vocabulary is root-relative), so without carrying the + // echo here a nested attribute that must mirror the request would + // land in the IR with no constraint at all. + reference_path, }, None => Binding::None, } @@ -482,40 +709,123 @@ fn classify_call( // `all_member_add`). Not an output field (the value is fixed); record it as a // Content assertion when on the same node. "literalContent" => { - if source_path.is_none() - && let Some(value) = args.get(2).and_then(arg_expr).and_then(as_string_lit) - { - assertions.push(ResponseAssertion { + let value = args.get(2).and_then(arg_expr).and_then(as_string_lit); + match value { + Some(value) if source_path.is_none() => assertions.push(ResponseAssertion { kind: AssertionKind::Content, name: None, value: Some(value.to_string()), - }); + reference_path: None, + }), + // A marker value supplied through a local constant or a computed + // expression. The disjunction still discriminates on it, so emitting no + // assertion AND no drop published fieldless variants with no usable + // discriminator while the diagnostics claimed nothing was lost. + None => resolver.drop_note_keyed( + "literalContent marker value not statically resolvable", + format!( + "{site}:{}", + source_path + .as_ref() + .map(|p| p.join("/")) + .unwrap_or_else(|| "".to_string()) + ), + ), + Some(_) => {} } Binding::None } - // `contentLiteralBytes(node, [..])` pins the node's content to a fixed byte - // sequence and returns it — a real bytes field when named in `makeResult`. - "contentLiteralBytes" => Binding::Field { - method: wap::CONTENT_BYTES.to_string(), - field_type: ParsedFieldType::Bytes, - required: true, - byte_length: None, - byte_range: None, - int_range: None, - wire_name: None, - source_path, - }, - // Optional literal → a present-or-absent marker; treat as optional string. - "optionalLiteral" => Binding::Field { - method: wap::MAYBE_ATTR_STRING.to_string(), - field_type: ParsedFieldType::String, - required: false, - byte_length: None, - byte_range: None, - int_range: None, - wire_name, - source_path, - }, + // `contentLiteralBytes(node, new Uint8Array([5]))` pins the node's content to a + // fixed byte sequence and returns it — a real bytes field when named in + // `makeResult`, but one where exactly one value is legal. Dropping the sequence + // published an unconstrained `bytes` field, telling an emitter any payload would + // do. The value rides as hex on `literalValue`, the same encoding the request + // side's `WapContent::const_bytes` uses, with its length on `byteLength`. + "contentLiteralBytes" => { + let bytes = args.get(1).and_then(arg_expr).and_then(static_byte_literal); + if bytes.is_none() { + // Keyed per OCCURRENCE, like every other reason here: a parser with two + // unresolvable byte pins has lost two constraints, and `site` alone + // folded them into one. The node path is what tells them apart. + let occurrence = source_path + .as_ref() + .map(|p| p.join("/")) + .unwrap_or_else(|| "".to_string()); + resolver.drop_note_keyed(BYTES_DROP, format!("{site}:{occurrence}")); + } + Binding::Field { + method: wap::CONTENT_BYTES.to_string(), + field_type: ParsedFieldType::Bytes, + required: true, + byte_length: bytes.as_ref().map(|b| b.len() as u32), + byte_range: None, + int_range: None, + wire_name: None, + source_path, + literal_value: bytes + .as_ref() + .map(|b| b.iter().map(|x| format!("{x:02x}")).collect::()), + enum_ref: None, + reference_path: None, + } + } + // `optionalLiteral(ACC, node, "attr", "value")` pins the attr *when present* — + // a present-or-absent marker, so it is NOT a variant discriminator (absence + // satisfies every sibling) and deliberately records no assertion. The pinned + // value still rides on the field: an emitter may omit `type` on a successful + // promote, but if it sends one it must be `"admin"` — sending a status code + // there is exactly the bug this carries the value to prevent. + "optionalLiteral" => { + let literal_value = args.get(3).and_then(arg_expr).and_then(static_literal); + let reference_path = args + .get(3) + .and_then(arg_expr) + .and_then(|e| reference_path_of(e, bindings)); + if literal_value.is_none() && reference_path.is_none() { + resolver.drop_note_keyed( + "optionalLiteral attr value not statically resolvable", + format!("{site}:{}", wire_name.clone().unwrap_or_default()), + ); + } + // The wrapped accessor decides the type, exactly as in the `literal` arm. + // `field_type` is what tells a consumer how to read `literalValue` back, so + // hardcoding `String` would actively mis-type an + // `optionalLiteral(attrInt, node, "code", 429)` pin. Falls back to a string + // when the accessor isn't resolvable (the overwhelmingly common `attrString`). + let (method, field_type, byte_length) = args + .first() + .and_then(arg_expr) + .and_then(inner_accessor_name) + .and_then(normalize_accessor) + .map(|(m, ft, bl)| (optional_variant(&m), ft, bl)) + .unwrap_or(( + wap::MAYBE_ATTR_STRING.to_string(), + ParsedFieldType::String, + None, + )); + Binding::Field { + method, + field_type, + required: false, + byte_length, + byte_range: None, + int_range: None, + wire_name, + source_path, + literal_value, + enum_ref: None, + reference_path, + } + } + // The `WASmaxParseReference` helpers read a value off the REQUEST, not the + // response node — the source of the `from`/`id` echo rules. + "attrStringFromReference" + | "optionalAttrStringFromReference" + | "attrFromReference" + | "optionalAttrFromReference" + | "contentStringFromReference" => { + classify_reference(method, args, resolver, reference_param, site) + } // `optional(ACCESSOR, node, …)` → the wrapped accessor decides the type; // required = false. "optional" => { @@ -526,7 +836,9 @@ fn classify_call( match inner.and_then(normalize_accessor) { Some((m, ft, bl)) => { let (field_type, int_range) = int_range_and_type(inner, args, ft); - let (cbl, byte_range) = content_byte_length(inner, args); + let (cbl, byte_range) = content_byte_length(inner, args, resolver, site); + let enum_ref = + enum_arg_ref(inner, args, resolver, site, source_path.as_deref()); Binding::Field { method: optional_variant(&m), field_type, @@ -536,6 +848,9 @@ fn classify_call( int_range, wire_name, source_path, + literal_value: None, + enum_ref, + reference_path: None, } } None => Binding::None, @@ -550,11 +865,13 @@ fn classify_call( | "optionalChild" | "optionalChildWithTag" | "flattenedChildWithTag" - | "mapChildrenWithTag" => classify_child(method, args, locals, resolver, visited, bindings), + | "mapChildrenWithTag" => classify_child(method, args, ctx, visited, bindings), other => match normalize_accessor(other) { Some((m, ft, bl)) => { let (field_type, int_range) = int_range_and_type(Some(other), args, ft); - let (cbl, byte_range) = content_byte_length(Some(other), args); + let (cbl, byte_range) = content_byte_length(Some(other), args, resolver, site); + let enum_ref = + enum_arg_ref(Some(other), args, resolver, site, source_path.as_deref()); Binding::Field { method: m, field_type, @@ -564,6 +881,9 @@ fn classify_call( int_range, wire_name, source_path, + literal_value: None, + enum_ref, + reference_path: None, } } None => Binding::None, @@ -571,6 +891,182 @@ fn classify_call( } } +/// A compile-time literal pinned as an assertion's expected value, stringified: +/// `"result"` → `"result"`, `429` → `"429"`, `!0`/`true` → `"true"`. The field's +/// declared type says how to read it back, so one string form covers every accessor +/// (an `attrInt` field's `"429"` is the integer 429 on the wire). +fn static_literal(e: &Expression) -> Option { + if let Some(s) = as_string_lit(e) { + return Some(s.to_string()); + } + if let Some(n) = as_int(e) { + return Some(n.to_string()); + } + match e { + Expression::BooleanLiteral(b) => Some(b.value.to_string()), + // The minifier writes booleans as `!0` / `!1`. + Expression::UnaryExpression(u) if u.operator == oxc_ast::ast::UnaryOperator::LogicalNot => { + as_int(&u.argument).map(|n| (n == 0).to_string()) + } + _ => None, + } +} + +/// The request path a `literal(…, V.value)` echo guard compares against, when `V` is +/// bound to a `WASmaxParseReference` helper. `None` for any other value expression — +/// this never infers an echo rule from a name coincidence. +fn reference_path_of(e: &Expression, bindings: &HashMap) -> Option> { + let (var, "value") = value_member(e)? else { + return None; + }; + match bindings.get(var) { + Some(Binding::Reference { path, .. }) => Some(path.clone()), + _ => None, + } +} + +/// Classify a `WASmaxParseReference` helper call into a [`Binding::Reference`]. +/// +/// The two shapes differ only in whether the accessor is passed explicitly: +/// `attrStringFromReference(request, ["to"])` — implicitly attrString +/// `attrFromReference(o("WASmaxParseJid").attrJidEnum, request, ["from"], ENUM)` +/// +/// The path argument is the helper's own contract: every element but the last is a +/// child tag to descend in the request, the last is the attribute read there. +fn classify_reference( + method: &str, + args: &[Argument], + resolver: &Resolver, + reference_param: Option<&str>, + site: &str, +) -> Binding { + let Some(path_idx) = args + .iter() + .position(|a| arg_expr(a).is_some_and(|e| string_array(e).is_some())) + else { + resolver.drop_note_keyed( + "reference path argument not statically resolvable", + format!("{site}:{method}"), + ); + return Binding::None; + }; + let path = arg_expr(&args[path_idx]) + .and_then(string_array) + .expect("position matched"); + // The node the path is walked from is the identifier argument just before it. It + // MUST be the parser's reference parameter: `referencePath` is documented as + // "relative to the request", and a consumer acting on it would be silently wrong if + // WA ever pointed a `…FromReference` helper at some other node. Enforce the + // invariant instead of trusting it — and count the rejection rather than dropping + // it silently, so the day it happens is visible. + let node = args[..path_idx] + .iter() + .rev() + .find_map(|a| arg_expr(a).and_then(as_identifier)); + if node.is_none() || node != reference_param { + resolver.drop_note_keyed( + "reference read from a node other than the request", + format!("{site}:{method}:{}", path.join("/")), + ); + return Binding::None; + } + // An explicit accessor (the `attrFromReference` family) decides the type; the + // `attrString…` spelling is fixed to a string. + let (base_method, field_type) = match method { + "contentStringFromReference" => (wap::CONTENT_STRING.to_string(), ParsedFieldType::String), + "attrStringFromReference" | "optionalAttrStringFromReference" => { + (wap::ATTR_STRING.to_string(), ParsedFieldType::String) + } + _ => args + .first() + .and_then(arg_expr) + .and_then(inner_accessor_name) + .and_then(normalize_accessor) + .map(|(m, ft, _)| (m, ft)) + .unwrap_or((wap::ATTR_STRING.to_string(), ParsedFieldType::String)), + }; + let optional = method.starts_with("optional"); + Binding::Reference { + path, + method: if optional { + optional_variant(&base_method) + } else { + base_method + }, + field_type, + required: !optional, + } +} + +/// An array literal of string literals (`["account","action"]`), or `None` if any +/// element isn't one. +fn string_array(e: &Expression) -> Option> { + let Expression::ArrayExpression(arr) = e else { + return None; + }; + arr.elements + .iter() + .map(|el| { + el.as_expression() + .and_then(as_string_lit) + .map(str::to_string) + }) + .collect::>>() + .filter(|v| !v.is_empty()) +} + +/// The wire enum an enum accessor validates against: the `o("Mod").ENUM_NAME` argument +/// of `attrStringEnum(node, "state", ENUM)` / `contentStringEnum(node, ENUM)`, resolved +/// to its variants. `None` for a non-enum accessor. +fn enum_arg_ref( + accessor: Option<&str>, + args: &[Argument], + resolver: &Resolver, + site: &str, + source_path: Option<&[String]>, +) -> Option { + // Gated on the CLASSIFIER, not a local list of spellings. Whitelisting + // `attrStringEnum`/`contentStringEnum` left `attrEnum`, `maybeAttrEnum`, `contentEnum` + // and `attrEnumOrNullIfUnknown` typed `enum` with no `enumRef` and no drop recorded — + // 77 fields whose validation constraint looked absent rather than lost. + if !accessor.is_some_and(|m| wap::method_field_type(m) == ParsedFieldType::Enum) { + return None; + } + // The enum is the only `o("Mod").NAME` member *reference* among the args (the node + // is an identifier / `X.value`, the attr a string, and — in the `optional(ACC, …)` + // form — the leading accessor ref is itself `o("WASmaxParseUtils").attrStringEnum`, + // excluded by requiring a non-`WASmaxParse*` owner module). + // The occurrence discriminator is the node PATH plus the attribute name: two fields + // validating against the same unresolvable enum are two lost constraints, and one + // parser reading `state` off both `` and `` is two of them. The + // attribute alone collapsed those into one. + let occurrence = format!( + "{site}:{}:{}", + source_path.map(|p| p.join("/")).unwrap_or_default(), + args.iter() + .filter_map(arg_expr) + .find_map(as_string_lit) + .unwrap_or("") + ); + let Some((module, name)) = args.iter().filter_map(arg_expr).find_map(module_member_ref) else { + // An inline enum object, a local alias, or a `WASmaxParse*`-owned reference: the + // accessor validates against SOMETHING we could not name. That is the exact + // "a constraint existed and we lost it" case the counter exists for. + resolver.drop_note_keyed(ENUM_DROP, format!("@{occurrence}")); + return None; + }; + resolver.resolve_enum(&module, &name, &occurrence) +} + +/// `o("Mod").NAME` (a member reference, not a call) → `(Mod, NAME)`, excluding the +/// `WASmaxParse*` helper namespaces (those are accessor references, not enums). +fn module_member_ref(e: &Expression) -> Option<(String, String)> { + let (obj, prop) = wa_oxc::as_member(e)?; + let inner = as_call(obj)?; + let owner = as_string_lit(arg_expr(inner.arguments.first()?)?)?; + (!owner.starts_with("WASmaxParse")).then(|| (owner.to_string(), prop.to_string())) +} + /// The wrapper tags descended to reach an accessor's node argument: the full /// [`Binding::ChildNode`] path when the node is `n.value` (a `flattenedChildWithTag` /// descent), or empty when the node is the parent param (no descent). The node is @@ -604,11 +1100,13 @@ fn node_descend_path( fn classify_child( method: &str, args: &oxc_allocator::Vec, - locals: &LocalFns, - resolver: &Resolver, + ctx: &FnCtx, visited: &mut HashSet, bindings: &HashMap, ) -> Binding { + let FnCtx { + locals, resolver, .. + } = *ctx; // The wire tag is the first string-literal arg. let Some(tag_idx) = args .iter() @@ -732,7 +1230,28 @@ fn int_range_and_type( fn content_byte_length( accessor: Option<&str>, args: &[Argument], + resolver: &Resolver, + site: &str, ) -> (Option, Option<(u32, u32)>) { + // `contentUint(N)` reads N big-endian bytes, so N is a fixed length like + // `contentBytes(N)`'s — not a bound. + if accessor == Some("contentUint") { + let n = args + .iter() + .filter_map(|a| arg_expr(a).and_then(as_int)) + .next(); + let width = n.and_then(|n| u32::try_from(n).ok()); + if width.is_none() { + // Recognizing the accessor PROVES an exact byte width exists — a hoisted + // constant hides the number, not the constraint. Returning nothing published + // an unrestricted integer with no signal that the width was lost. + resolver.drop_note_keyed( + "contentUint width not statically resolvable", + site.to_string(), + ); + } + return (width, None); + } if accessor != Some("contentBytesRange") { return (None, None); } @@ -747,44 +1266,51 @@ fn content_byte_length( } } -/// Map a smax accessor name → (canonical wap method, field type, byte_length). +/// Map a smax accessor name → its canonical wap method and the type that method decodes +/// to. +/// +/// This table decides **only the name**. The type comes from [`wap::method_field_type`], +/// so there is exactly one classifier in the codebase and the two cannot drift — they +/// already had, twice: `attrJidWithType` carried `jid` here and `jid_typed` there for the +/// same wire contract, and the enum accessors were `enum` on one side and `string` on the +/// other. A local table that repeats the type is a second source of truth waiting to go +/// stale, so this one does not have one. +/// +/// Aliasing is what remains: `attrStanzaId` and `attrCallId` are `attrString` reads under +/// another name, `attrPhoneUserJid` is the explicit-PN spelling of `attrUserJid`, and +/// `contentBytesRange` is `contentBytes` with a length rule. Anything not aliased keeps +/// its own name, which is how the JID flavour — protocol-safety-critical, since a LID and +/// a PN user JID are different identities for the same person — survives. fn normalize_accessor(m: &str) -> Option<(String, ParsedFieldType, Option)> { - let s = |c: &str, t: ParsedFieldType| Some((c.to_string(), t, None)); - match m { - "attrString" | "attrStanzaId" | "attrCallId" | "attrStringFromReference" => { - s(wap::ATTR_STRING, ParsedFieldType::String) - } - "attrInt" | "attrIntRange" => s(wap::ATTR_INT, ParsedFieldType::Integer), - "attrStringEnum" => s(wap::ATTR_ENUM, ParsedFieldType::Enum), - "contentString" => s(wap::CONTENT_STRING, ParsedFieldType::String), - "contentInt" => s(wap::CONTENT_INT, ParsedFieldType::Integer), - "contentStringEnum" => s(wap::ATTR_ENUM, ParsedFieldType::Enum), - "contentBytes" => s(wap::CONTENT_BYTES, ParsedFieldType::Bytes), - "contentBytesRange" => s(wap::CONTENT_BYTES, ParsedFieldType::Bytes), - // Keep the JID flavor each accessor validates rather than collapsing every JID - // to one type. The flavor is protocol-safety-critical: a LID user JID and a PN - // user JID are different identities for the same person. The `phone*` variants - // are the explicit-PN spelling of the plain user/device accessors. - "attrUserJid" | "attrPhoneUserJid" => s(wap::ATTR_USER_JID, ParsedFieldType::UserJid), - "attrLidUserJid" => s(wap::ATTR_LID_USER_JID, ParsedFieldType::LidUserJid), - "attrDeviceJid" | "attrPhoneDeviceJid" => { - s(wap::ATTR_DEVICE_JID, ParsedFieldType::DeviceJid) - } - "attrLidDeviceJid" => s(wap::ATTR_LID_DEVICE_JID, ParsedFieldType::LidDeviceJid), - "attrGroupJid" => s(wap::ATTR_GROUP_JID, ParsedFieldType::GroupJid), - "attrNewsletterJid" => s(wap::ATTR_NEWSLETTER_JID, ParsedFieldType::NewsletterJid), - "attrCallJid" => s(wap::ATTR_CALL_JID, ParsedFieldType::CallJid), - "attrBroadcastJid" => s(wap::ATTR_BROADCAST_JID, ParsedFieldType::BroadcastJid), - "attrStatusJid" => s(wap::ATTR_STATUS_JID, ParsedFieldType::StatusJid), - // Generic / multi-flavor accessors stay a bare Jid: `attrChatJid` is a user OR - // a group, `attrJid`/`attrDomainJid` accept any, `attrJidEnum` pins the server - // kind via a runtime enum arg (no single static flavor). - "attrJid" | "attrDomainJid" | "attrChatJid" | "attrPhoneChatJid" | "attrWapJid" - | "attrFromJid" | "attrFromPhoneJid" | "attrLidJid" | "attrJidEnum" | "literalJid" => { - s(wap::ATTR_JID_WITH_TYPE, ParsedFieldType::Jid) - } - _ => None, - } + let canonical = match m { + "attrStanzaId" | "attrCallId" | "attrStringFromReference" => wap::ATTR_STRING, + "attrIntRange" => wap::ATTR_INT, + "attrStringEnum" => wap::ATTR_ENUM, + // A content enum must keep a CONTENT spelling: codegen switches on the method to + // decide whether to read an attribute or the element body, so rewriting this to + // `attrEnum` made the generated parser look for an attribute that does not exist. + "contentStringEnum" => "contentEnum", + "contentBytesRange" => wap::CONTENT_BYTES, + "attrPhoneUserJid" => wap::ATTR_USER_JID, + "attrPhoneDeviceJid" => wap::ATTR_DEVICE_JID, + // Not aliased: the accessor names itself, and the classifier types it. + other if is_known_accessor(other) => other, + _ => return None, + }; + Some(( + canonical.to_string(), + wap::method_field_type(canonical), + None, + )) +} + +/// Whether the classifier recognises this accessor as a value read at all. +/// +/// A smax parser calls plenty of helpers that are not field accessors (`assertTag`, +/// `optional`, the child descents), so an unknown name must yield no field rather than a +/// defaulted string — the callers rely on `None` to skip. +fn is_known_accessor(m: &str) -> bool { + wap::is_attr_method(m) || wap::is_content_method(m) } /// The optional (`maybe…`) variant of a canonical method, where one exists. @@ -1042,12 +1568,26 @@ fn collect_object_fields( // A boolean presence flag: `{hasX: V.success}` or `{hasX: V.value != null}` // — the key records whether a sub-node/attr was present, not its value. The // wire name (when known) is the underlying accessor's attr. + // + // The *pin* underneath survives too. The blocklist shapes bind + // `optionalLiteral(attrString, list, "c_dhash", ref.item.dhash)` and then expose + // only `{hasListCDhash: m.value != null}`: the attribute is optional, but if it + // is present the parser requires it to equal the request's ``. + // Dropping the pin here would lose that rule entirely — the flag would say + // "c_dhash may appear" and nothing would say what it must contain. if let Some(flag_var) = bool_flag_var(&p.value) { + let underlying = bindings.get(flag_var); out.push(ParsedField { name: key.to_string(), field_type: ParsedFieldType::Bool, - wire_name: bindings.get(flag_var).and_then(binding_wire_name), + wire_name: underlying.and_then(binding_wire_name), required: true, + literal_value: underlying.and_then(binding_literal_value), + reference_path: underlying.and_then(binding_reference_path), + // The flag reports on an attribute of whatever node the underlying + // accessor read — ``, not the `` root. Dropping the + // path sends a consumer to apply the echo one level too high. + source_path: underlying.and_then(binding_source_path), ..Default::default() }); continue; @@ -1073,6 +1613,9 @@ fn collect_object_fields( int_range, wire_name, source_path, + literal_value, + enum_ref, + reference_path, }) => { let (int_min, int_max) = match int_range { Some((min, max)) => (Some(*min), Some(*max)), @@ -1094,6 +1637,31 @@ fn collect_object_fields( int_min, int_max, source_path: source_path.clone(), + literal_value: literal_value.clone(), + enum_ref: enum_ref.clone(), + reference_path: reference_path.clone(), + ..Default::default() + }); + } + // A value the parser lifts from the REQUEST and the tail names as an output + // field. Its wire name is the last path element (the attribute read there); + // the wrappers above it, when any, are the request-side descent. + Some(Binding::Reference { + path, + method, + field_type, + required, + }) => { + out.push(ParsedField { + method: method.clone(), + name: key.to_string(), + wire_name: path.last().cloned(), + field_type: *field_type, + required: *required && !optional, + // The value IS the request's. Keeping the path makes that machine- + // visible; without it the field is indistinguishable from one read + // off the response node. + reference_path: Some(path.clone()), ..Default::default() }); } @@ -1344,6 +1912,33 @@ fn is_nullish(e: &Expression) -> bool { fn binding_wire_name(b: &Binding) -> Option { match b { Binding::Field { wire_name, .. } => wire_name.clone(), + Binding::Reference { path, .. } => path.last().cloned(), + _ => None, + } +} + +/// The wrapper tags a binding descends before reading, when it reads off a child node. +fn binding_source_path(b: &Binding) -> Option> { + match b { + Binding::Field { source_path, .. } => source_path.clone(), + _ => None, + } +} + +/// The constant a binding pins its value to, when it is a `literal`/`optionalLiteral`. +fn binding_literal_value(b: &Binding) -> Option { + match b { + Binding::Field { literal_value, .. } => literal_value.clone(), + _ => None, + } +} + +/// The request path a binding echoes, whether it is the echo itself +/// (`attrStringFromReference`) or an `optionalLiteral` pinned to one. +fn binding_reference_path(b: &Binding) -> Option> { + match b { + Binding::Field { reference_path, .. } => reference_path.clone(), + Binding::Reference { path, .. } => Some(path.clone()), _ => None, } } @@ -1496,6 +2091,77 @@ impl Resolver<'_> { } } +/// A compile-time byte sequence: `new Uint8Array([5])`, `Uint8Array.of(1, 2)`, or a bare +/// `[0, 1]`. `None` for anything computed — the caller counts that as a dropped +/// constraint rather than publishing the field as unconstrained. +/// +/// Shared with the legacy scanner, which reaches `contentLiteralBytes` by a different +/// route and must pin the same value from the same spelling. +/// Upper bound on a `new Uint8Array(N)` zero-fill we will materialize as a literal. A +/// pin longer than this is not a wire constant anyone writes; the cap keeps a bogus or +/// hostile length from allocating. +const MAX_ZERO_FILL: i64 = 4096; + +pub(crate) fn static_byte_literal(e: &Expression) -> Option> { + // `Uint8Array.of(1, 2)` — the bytes are the ARGUMENTS, not an array operand. It was + // documented as supported here and was not: every call expression fell through to + // `None` and the pin was reported as an unresolved constraint. + // The receiver must be `Uint8Array`: `factory.of(1, 2)` is an ordinary call that may + // return anything, and reading its arguments as the pinned bytes would invent a + // `literalValue` rather than record an unresolved one. + if let Some(call) = wa_oxc::as_call(e) + && callee_method(call) == Some("of") + && callee_object(call).and_then(as_identifier) == Some("Uint8Array") + { + return call + .arguments + .iter() + .map(|a| arg_expr(a).and_then(byte_literal)) + .collect(); + } + let elements = match e { + Expression::ArrayExpression(a) => a, + Expression::NewExpression(n) => { + // The constructor is checked for the same reason the `.of` receiver is: + // `new Whatever([1,2])` need not produce those bytes. + if as_identifier(&n.callee) != Some("Uint8Array") { + return None; + } + match arg_expr(n.arguments.first()?)? { + Expression::ArrayExpression(a) => a, + // `new Uint8Array(4)` is a LENGTH — and therefore exactly four ZERO + // bytes, which is as much a compile-time constant as a literal array. + // Refusing it lost a recoverable pin; reading the `4` as the byte 0x04 + // would have invented a different one. The request side's constant index + // already models this form the same way. + e => { + let n = as_int(e).filter(|n| (0..=MAX_ZERO_FILL).contains(n))?; + return Some(vec![0u8; n as usize]); + } + } + } + _ => return None, + }; + elements + .elements + .iter() + .map(|el| byte_literal(el.as_expression()?)) + .collect() +} + +/// One numeric literal that is exactly a byte. Fractions are rejected rather than +/// truncated: `1.5 as u8` is `1`, a pinned value the source never states. +fn byte_literal(e: &Expression) -> Option { + match e { + Expression::NumericLiteral(n) + if n.value.fract() == 0.0 && (0.0..=255.0).contains(&n.value) => + { + Some(n.value as u8) + } + _ => None, + } +} + #[cfg(test)] mod tests { use super::*; @@ -1514,6 +2180,51 @@ mod tests { analyze_module_exports(module, &resolver) } + #[test] + fn an_unresolvable_literal_content_marker_is_counted() { + // A disjunction discriminates on `literalContent`. When the marker value arrives + // through a local constant rather than an inline string, emitting neither an + // assertion nor a drop published a fieldless variant with no usable + // discriminator while the diagnostics claimed nothing was lost. + let slices = HashMap::new(); + let resolver = Resolver::new(&slices); + let (asserts, _) = analyze_fn_source( + r#"function p(node){ + var v = MARKER; + var a = o("WASmaxParseUtils").literalContent(node, "x", v); + return o("WAResultOrError").makeResult({}); + }"#, + &LocalFns::new(), + &resolver, + &mut HashSet::new(), + ) + .expect("analyzed"); + assert!( + !asserts.iter().any(|a| a.kind == AssertionKind::Content), + "no discriminator is invented" + ); + assert_eq!( + resolver + .drop_counts() + .get("literalContent marker value not statically resolvable"), + Some(&1), + "but the loss is reported" + ); + } + + #[test] + fn a_content_enum_keeps_a_content_spelling() { + // `contentStringEnum(node, TABLE)` reads the ELEMENT BODY. Normalizing it to + // `attrEnum` made codegen emit an attribute read for a value that is not an + // attribute, so the generated parser looked for something that never exists. + assert_eq!( + normalize_accessor("contentStringEnum").map(|(m, t, _)| (m, t)), + Some(("contentEnum".to_string(), wa_ir::ParsedFieldType::Enum)), + "content spelling preserved, enum type kept" + ); + assert!(wa_ir::wap::is_content_method("contentEnum")); + } + #[test] fn attrs_and_literal_assertion() { // attrString → field; literal(...) → assertion, no field; type from binding. @@ -1619,6 +2330,290 @@ mod tests { assert!(names.contains(&"type"), "mixin fields spread in"); } + #[test] + fn reference_echo_becomes_a_reference_assertion() { + // The rule 17 of the 26 namespace error mixins enforce (and every success + // parser): `from` must equal the REQUEST's `to`, `id` the request's `id`. Both + // must land as `reference` assertions carrying where the value comes from — + // an emitter that hardcodes `from="s.whatsapp.net"` breaks every `g.us` answer. + let body = r#"function e(node, ref){ + var n = o("WASmaxParseUtils").assertTag(node, "iq"); if(!n.success) return n; + var r = o("WASmaxParseReference").attrStringFromReference(ref, ["id"]); if(!r.success) return r; + var a = o("WASmaxParseUtils").literal(o("WASmaxParseUtils").attrString, node, "id", r.value); if(!a.success) return a; + var i = o("WASmaxParseReference").attrStringFromReference(ref, ["to"]); if(!i.success) return i; + var l = o("WASmaxParseUtils").literal(o("WASmaxParseUtils").attrString, node, "from", i.value); if(!l.success) return l; + var s = o("WASmaxParseUtils").literal(o("WASmaxParseUtils").attrString, node, "type", "error"); + return s.success ? o("WAResultOrError").makeResult({ type: s.value }) : s; + }"#; + let (asserts, fields) = analyze_one(body).expect("analyzed"); + let by = |name: &str| { + asserts + .iter() + .find(|a| a.name.as_deref() == Some(name)) + .unwrap_or_else(|| panic!("no assertion for {name}")) + }; + assert_eq!(by("from").kind, AssertionKind::Reference); + assert_eq!( + by("from").reference_path.as_deref(), + Some(&["to".to_string()][..]) + ); + assert_eq!(by("from").value, None, "a reference has no constant value"); + assert_eq!(by("id").kind, AssertionKind::Reference); + assert_eq!( + by("id").reference_path.as_deref(), + Some(&["id".to_string()][..]) + ); + // A constant literal is still a plain attr assertion, with its value. + assert_eq!(by("type").kind, AssertionKind::Attr); + assert_eq!(by("type").value.as_deref(), Some("error")); + // …and it is also the `type` output field, now carrying its pinned value. + let ty = fields + .iter() + .find(|f| f.name == "type") + .expect("type field"); + assert_eq!(ty.literal_value.as_deref(), Some("error")); + } + + #[test] + fn a_reference_off_a_node_other_than_the_request_is_rejected() { + // `referencePath` is documented as relative to the REQUEST, and a consumer acts + // on that. If WA ever pointed a `…FromReference` helper at some other node, an + // echo rule read as "the request's" would be silently wrong — so the invariant + // is enforced, and the rejection is counted rather than dropped in silence. + let slices = HashMap::new(); + let resolver = Resolver::new(&slices); + // `node` is the FIRST parameter (the response), not the reference. + let body = r#"function e(node, ref){ + var r = o("WASmaxParseReference").attrStringFromReference(node, ["id"]); if(!r.success) return r; + var a = o("WASmaxParseUtils").literal(o("WASmaxParseUtils").attrString, node, "id", r.value); + return o("WAResultOrError").makeResult({ id: a.value }); + }"#; + let (asserts, _f) = + analyze_fn_source(body, &LocalFns::new(), &resolver, &mut HashSet::new()) + .expect("analyzed"); + assert!( + !asserts.iter().any(|a| a.kind == AssertionKind::Reference), + "an echo off a non-request node must not be reported as a request echo" + ); + assert_eq!( + resolver + .drop_counts() + .get("reference read from a node other than the request"), + Some(&1) + ); + } + + #[test] + fn a_required_echo_on_a_descended_node_survives() { + // A `literal` on a node reached through `flattenedChildWithTag` records no root + // assertion — the assertion vocabulary is root-relative — so the echo has to ride + // on the field, or the nested attribute reaches the IR with no constraint at all + // and an emitter can put anything there. + let body = r#"function e(node, ref){ + var t = o("WASmaxParseUtils").flattenedChildWithTag(node, "list"); if(!t.success) return t; + var r = o("WASmaxParseReference").attrStringFromReference(ref, ["id"]); if(!r.success) return r; + var a = o("WASmaxParseUtils").literal(o("WASmaxParseUtils").attrString, t.value, "id", r.value); + return o("WAResultOrError").makeResult({ listId: a.value }); + }"#; + let (asserts, fields) = analyze_one(body).expect("analyzed"); + assert!( + !asserts.iter().any(|a| a.kind == AssertionKind::Reference), + "the guard is on , not the root, so it must not become a root assertion" + ); + let f = fields.iter().find(|f| f.name == "listId").expect("listId"); + assert_eq!(f.source_path.as_deref(), Some(&["list".to_string()][..])); + assert_eq!(f.reference_path.as_deref(), Some(&["id".to_string()][..])); + } + + #[test] + fn multi_hop_reference_path_is_kept_whole() { + // `attrStringFromReference(request, ["account","action"])` reads the `action` + // attr of the request's `` CHILD — the descent must survive. + let body = r#"function e(node, ref){ + var r = o("WASmaxParseReference").attrStringFromReference(ref, ["account","action"]); if(!r.success) return r; + var a = o("WASmaxParseUtils").literal(o("WASmaxParseUtils").attrString, node, "action", r.value); + return o("WAResultOrError").makeResult({ action: a.value }); + }"#; + let (asserts, _f) = analyze_one(body).expect("analyzed"); + let a = asserts + .iter() + .find(|a| a.kind == AssertionKind::Reference) + .expect("reference assertion"); + assert_eq!( + a.reference_path.as_deref(), + Some(&["account".to_string(), "action".to_string()][..]) + ); + } + + #[test] + fn numeric_literal_pins_both_the_assertion_and_the_field() { + // The error mixins pin `code` with an INT literal; dropping it would leave the + // per-RPC error vocabulary with texts but no codes. + let body = r#"function e(node){ + var t = o("WASmaxParseUtils").assertTag(node, "error"); if(!t.success) return t; + var n = o("WASmaxParseUtils").literal(o("WASmaxParseUtils").attrString, node, "text", "rate-overlimit"); if(!n.success) return n; + var r = o("WASmaxParseUtils").literal(o("WASmaxParseUtils").attrInt, node, "code", 429); + return r.success ? o("WAResultOrError").makeResult({ text: n.value, code: r.value }) : r; + }"#; + let (asserts, fields) = analyze_one(body).expect("analyzed"); + let code_assert = asserts + .iter() + .find(|a| a.name.as_deref() == Some("code")) + .expect("code assertion"); + assert_eq!(code_assert.value.as_deref(), Some("429")); + let code = fields + .iter() + .find(|f| f.name == "code") + .expect("code field"); + assert_eq!(code.literal_value.as_deref(), Some("429")); + assert_eq!(code.field_type, ParsedFieldType::Integer); + } + + #[test] + fn optional_literal_pins_a_value_without_asserting_it() { + // `optionalLiteral(attrString, participant, "type", "admin")` — a successful + // promote answers ``. The value must ride on the + // field (barback sent a status code there), but it must NOT become an + // assertion: absence is legal, so it discriminates nothing. + let body = r#"function e(node){ + var s = o("WASmaxParseUtils").optionalLiteral(o("WASmaxParseUtils").attrString, node, "type", "admin"); + return o("WAResultOrError").makeResult({ type: s.value }); + }"#; + let (asserts, fields) = analyze_one(body).expect("analyzed"); + assert!( + !asserts.iter().any(|a| a.name.as_deref() == Some("type")), + "an optional literal is not a discriminator" + ); + let ty = fields + .iter() + .find(|f| f.name == "type") + .expect("type field"); + assert_eq!(ty.literal_value.as_deref(), Some("admin")); + assert!(!ty.required, "optionalLiteral → the attr may be absent"); + } + + #[test] + fn optional_literal_can_pin_to_a_request_value() { + // `optionalLiteral(attrString, list, "c_dhash", ref.item.dhash)` — an echo that + // is NOT a guard (the attr may be absent), so it rides on the field rather than + // becoming an assertion. Without it the rule would only be countable as a drop. + let body = r#"function e(node, ref){ + var m = o("WASmaxParseReference").optionalAttrStringFromReference(ref, ["item","dhash"]); + var s = o("WASmaxParseUtils").optionalLiteral(o("WASmaxParseUtils").attrString, node, "c_dhash", m.value); + return o("WAResultOrError").makeResult({ cDhash: s.value }); + }"#; + let (asserts, fields) = analyze_one(body).expect("analyzed"); + assert!( + !asserts.iter().any(|a| a.kind == AssertionKind::Reference), + "an optional echo guards nothing, so it is not an assertion" + ); + let f = fields.iter().find(|f| f.name == "cDhash").expect("field"); + assert_eq!( + f.reference_path.as_deref(), + Some(&["item".to_string(), "dhash".to_string()][..]) + ); + assert_eq!(f.literal_value, None, "an echo is not a constant"); + assert!(!f.required); + } + + #[test] + fn enum_accessor_resolves_its_variants() { + // A response enum field must carry the legal values, not just `type: "enum"`. + let enums = r#"__d("WASmaxInFooEnums",[],(function(t,n,r,o,a,i){ + var e={off:"off",on:"on"}; i.ENUM_OFF_ON=e; + }),66);"#; + let mut slices = HashMap::new(); + slices.insert("WASmaxInFooEnums", enums); + let resolver = Resolver::new(&slices); + let body = r#"function e(node){ + var s = o("WASmaxParseUtils").attrStringEnum(node, "state", o("WASmaxInFooEnums").ENUM_OFF_ON); if(!s.success) return s; + var t = o("WASmaxParseUtils").optional(o("WASmaxParseUtils").attrStringEnum, node, "mode", o("WASmaxInFooEnums").ENUM_OFF_ON); + return o("WAResultOrError").makeResult({ state: s.value, mode: t.value }); + }"#; + let (_a, fields) = + analyze_fn_source(body, &LocalFns::new(), &resolver, &mut HashSet::new()) + .expect("analyzed"); + for name in ["state", "mode"] { + let f = fields.iter().find(|f| f.name == name).expect(name); + let er = f.enum_ref.as_ref().unwrap_or_else(|| panic!("{name} enum")); + assert_eq!(er.name, "ENUM_OFF_ON"); + assert_eq!(er.module, "WASmaxInFooEnums"); + let values: Vec<&str> = er.variants.iter().map(|v| v.value.as_str()).collect(); + assert_eq!(values, ["off", "on"]); + } + } + + #[test] + fn two_parsers_losing_the_same_enum_are_two_lost_constraints() { + // The counter's unit is distinct LOST CONSTRAINTS, so keying on the enum — or on + // the enum plus the attribute — collapses separate parsers reading the same thing + // and lets constraints disappear without moving the number. The parser body is + // part of the key; the two analysis passes over one body still count once. + let slices = HashMap::new(); + let resolver = Resolver::new(&slices); + let one = r#"function e(node){ + var s = o("WASmaxParseUtils").attrStringEnum(node, "state", o("Missing").ENUM_X); if(!s.success) return s; + return o("WAResultOrError").makeResult({ state: s.value }); + }"#; + let two = r#"function e(node){ + var t = o("WASmaxParseUtils").assertTag(node, "iq"); if(!t.success) return t; + var s = o("WASmaxParseUtils").attrStringEnum(node, "state", o("Missing").ENUM_X); if(!s.success) return s; + return o("WAResultOrError").makeResult({ state: s.value }); + }"#; + let count = || { + resolver + .drop_counts() + .get("response enum argument not structurally resolvable") + .copied() + .unwrap_or(0) + }; + analyze_fn_source(one, &LocalFns::new(), &resolver, &mut HashSet::new()); + assert_eq!(count(), 1); + // Re-analyzing the SAME body (as the assertion pass does) must not double-count. + analyze_fn_source(one, &LocalFns::new(), &resolver, &mut HashSet::new()); + assert_eq!(count(), 1, "the same site analyzed twice is one loss"); + // A DIFFERENT parser losing the same enum on the same attribute is a second loss. + analyze_fn_source(two, &LocalFns::new(), &resolver, &mut HashSet::new()); + assert_eq!(count(), 2, "distinct parser sites are distinct losses"); + } + + #[test] + fn unresolvable_enum_is_recorded_not_guessed() { + // The enum module isn't in the bundle: no link, and a drop reason so a consumer + // can tell "no enum here" from "there was one and we lost it". + let slices = HashMap::new(); + let resolver = Resolver::new(&slices); + let body = r#"function e(node){ + var s = o("WASmaxParseUtils").attrStringEnum(node, "state", o("Missing").ENUM_OFF_ON); if(!s.success) return s; + return o("WAResultOrError").makeResult({ state: s.value }); + }"#; + let (_a, fields) = + analyze_fn_source(body, &LocalFns::new(), &resolver, &mut HashSet::new()) + .expect("analyzed"); + assert!(fields[0].enum_ref.is_none()); + assert_eq!( + resolver + .drop_counts() + .get("response enum argument not structurally resolvable"), + Some(&1) + ); + } + + #[test] + fn reference_value_named_in_make_result_is_still_a_field() { + // A reference binding usually only feeds an echo guard, but when the tail names + // it, it is a real output field — it must not vanish just because it reads off + // the request. + let body = r#"function e(node, ref){ + var r = o("WASmaxParseReference").attrStringFromReference(ref, ["id"]); if(!r.success) return r; + return o("WAResultOrError").makeResult({ id: r.value }); + }"#; + let (_a, fields) = analyze_one(body).expect("analyzed"); + let id = fields.iter().find(|f| f.name == "id").expect("id field"); + assert_eq!(id.wire_name.as_deref(), Some("id")); + assert!(id.required); + } + #[test] fn unrecognized_tail_yields_none() { let body = r#"function e(node){ return somethingElse(node); }"#; diff --git a/crates/wa-scan/tests/iq_roundtrip.rs b/crates/wa-scan/tests/iq_roundtrip.rs new file mode 100644 index 0000000..3dcbcd3 --- /dev/null +++ b/crates/wa-scan/tests/iq_roundtrip.rs @@ -0,0 +1,576 @@ +//! Guard: the committed IQ IR carries enough to **emit** a stanza, not only to read one. +//! +//! The IR has always described what fields a stanza has. That is enough to parse a +//! well-formed response and not enough to produce one — which is how a mock server can +//! answer a successful `promote` with `` (a status code where +//! the role goes) and have a real client reject the whole thing, or answer an `` +//! addressed to `g.us` with `from="s.whatsapp.net"` and be unparseable. +//! +//! So this test closes the loop the way a consumer would: for every `` success +//! shape, build a stanza from **the IR alone** — nothing but the recorded assertions and +//! pinned field values — and check the recorded constraints accept it. A constraint the +//! IR fails to carry shows up here as an emitted stanza that the same IR then rejects. +//! +//! The stanza is modelled as a **tree**, addressed by the path from the root, because +//! the constraints that motivated the change do not live on the root: `matched="true"` +//! sits on the `` child (a `sourcePath`) and `type="admin"` on `` (a +//! nested `child` field). A root-only guard would accept exactly the malformed promote +//! response this file exists to reject. +//! +//! Both halves are deliberately naive: the emitter only knows how to satisfy +//! constraints, and the checker only knows how to verify them. Neither shares code with +//! the extractor, so a mis-extracted constraint cannot cancel itself out. +//! +//! # What this does NOT catch +//! +//! An **omitted** constraint. Emitter and checker read the same recorded field list, so a +//! pin the extractor never wrote is invisible to both: they agree on the unconstrained +//! shape and the round trip passes. This guard proves the recorded constraints are +//! mutually satisfiable and correctly placed — not that none is missing. +//! +//! Omissions are caught elsewhere, by two mechanisms that do have an outside reference: +//! `manifest.diagnostics.iq.constraints`, floored against the previously committed run, +//! and the named canaries at the bottom of this file, which assert that the specific +//! rules this domain exists for are still present by name. + +use std::collections::BTreeMap; +use std::path::Path; + +use wa_ir::{AssertionKind, IqIr, ParsedField, ResponseAssertion, ResponseVariantKind}; + +/// A stanza under construction: the root tag, its text content, and the attributes of +/// every node reachable in it, keyed by the path from the root (`[]` is the root itself, +/// `["list"]` its `` child, `["participant"]` a `` child, …). +#[derive(Debug, Default)] +struct Stanza { + tag: String, + content: Option, + nodes: BTreeMap, BTreeMap>, +} + +impl Stanza { + fn attr(&self, path: &[String], name: &str) -> Option<&String> { + self.nodes.get(path).and_then(|n| n.get(name)) + } + fn set(&mut self, path: Vec, name: String, value: String) { + self.nodes + .entry(path) + .or_default() + .entry(name) + .or_insert(value); + } +} + +/// The request a response is answering, as far as the echo rules care: the attribute +/// values a `reference` constraint can point at. Keyed by the joined path, so a +/// multi-hop one (`["account","action"]`) is addressable too. +fn sample_request() -> BTreeMap { + // A group-addressed request — the case that broke: `to` is NOT `s.whatsapp.net`, so + // an emitter that hardcodes the server JID fails the `from` echo. + BTreeMap::from([ + ("id".to_string(), "1234.5678-9".to_string()), + ("to".to_string(), "120363000000000000@g.us".to_string()), + ("type".to_string(), "set".to_string()), + ("account/action".to_string(), "sync".to_string()), + ("item/dhash".to_string(), "2:abcdef==".to_string()), + ( + "participant".to_string(), + "5511999999999@s.whatsapp.net".to_string(), + ), + ("category".to_string(), "block".to_string()), + ]) +} + +/// The value a field is pinned to, if any: a constant, or the request value it echoes. +/// `Err` marks a pin whose request path the sample doesn't model — not an IR failure, +/// but an unrecognised shape that must be reported rather than pass silently. +fn pinned_value( + f: &ParsedField, + request: &BTreeMap, +) -> Option> { + if let Some(v) = &f.literal_value { + return Some(Ok(v.clone())); + } + let path = f.reference_path.as_ref()?; + Some( + request + .get(&path.join("/")) + .cloned() + .ok_or_else(|| format!("unmodelled request path {path:?}")), + ) +} + +/// Walk a field tree, invoking `visit` with each pinned field and the path of the node +/// it is read from. +/// +/// Three shapes decide the path: `sourcePath` prepends wrapper tags to descend, a +/// `child` field descends into its own `tag`, and a `sameNode` mixin reads off the +/// parent without descending at all. +/// +/// Only a **required** container is descended into. An optional one is a branch the +/// response need not take, and WA models mutually exclusive alternatives as several +/// optional same-node mixins rather than as one union: a newsletter `` +/// carries an `InteractionTypeQuestion` mixin pinning `interaction_type="question"` and +/// an `InteractionTypeQuestionReshare` mixin pinning `"question_reshare"` on the very +/// same attribute. Both pins are correct; only one applies at a time. Descending into +/// both would build a self-contradicting node and report the IR as broken when it is +/// the walk that is wrong. Unions are skipped for the same reason unless single-armed. +fn walk_pinned( + fields: &[ParsedField], + base: &[String], + visit: &mut impl FnMut(&ParsedField, Vec), +) { + for f in fields { + let mut path = base.to_vec(); + if !f.same_node { + path.extend(f.source_path.iter().flatten().cloned()); + if let Some(tag) = &f.tag { + path.push(tag.clone()); + } + } + if f.literal_value.is_some() || f.reference_path.is_some() { + visit(f, path.clone()); + } + if !f.required { + continue; // a branch the response need not take — see above + } + if let Some(children) = &f.children { + walk_pinned(children, &path, visit); + } + if let Some([only]) = f.union_variants.as_deref() { + walk_pinned(&only.fields, &path, visit); + } + } +} + +/// Build the response a shape describes, using only the IR. +fn emit(assertions: &[ResponseAssertion], fields: &[ParsedField]) -> Stanza { + let request = sample_request(); + let mut s = Stanza::default(); + let root: Vec = Vec::new(); + for a in assertions { + match a.kind { + AssertionKind::Tag => s.tag = a.name.clone().unwrap_or_default(), + AssertionKind::Attr => { + if let (Some(name), Some(value)) = (&a.name, &a.value) { + s.set(root.clone(), name.clone(), value.clone()); + } + } + AssertionKind::Content => s.content = a.value.clone(), + // The whole point of the `reference` kind: the emitter reads the expected + // value out of the REQUEST rather than inventing one. + AssertionKind::Reference => { + if let (Some(name), Some(path)) = (&a.name, &a.reference_path) + && let Some(value) = request.get(&path.join("/")) + { + s.set(root.clone(), name.clone(), value.clone()); + } + } + AssertionKind::FromServer => {} + } + } + // A required pin must be emitted; an optional one may be omitted (and this emitter + // omits it, which the checker must accept). + walk_pinned(fields, &root, &mut |f, path| { + if !pin_is_required(f) { + return; + } + if let Some(Ok(value)) = pinned_value(f, &request) { + let wire = f.wire_name.clone().unwrap_or_else(|| f.name.clone()); + s.set(path, wire, value); + } + }); + s +} + +/// Check the stanza against the same constraints, reporting each unsatisfied one. +fn violations(s: &Stanza, assertions: &[ResponseAssertion], fields: &[ParsedField]) -> Vec { + let request = sample_request(); + let root: Vec = Vec::new(); + let mut out = Vec::new(); + for a in assertions { + match a.kind { + AssertionKind::Tag => { + if let Some(tag) = &a.name + && &s.tag != tag + { + out.push(format!("tag: expected <{tag}>, got <{}>", s.tag)); + } + } + AssertionKind::Attr => { + if let (Some(name), Some(value)) = (&a.name, &a.value) + && s.attr(&root, name) != Some(value) + { + out.push(format!( + "attr {name}: expected {value:?}, got {:?}", + s.attr(&root, name) + )); + } + } + AssertionKind::Content => { + if s.content.as_ref() != a.value.as_ref() { + out.push(format!( + "content: expected {:?}, got {:?}", + a.value, s.content + )); + } + } + AssertionKind::Reference => { + let Some(name) = &a.name else { continue }; + let Some(path) = &a.reference_path else { + out.push(format!("reference {name}: no referencePath recorded")); + continue; + }; + let Some(expected) = request.get(&path.join("/")) else { + out.push(format!( + "reference {name}: unmodelled request path {path:?}" + )); + continue; + }; + if s.attr(&root, name) != Some(expected) { + out.push(format!( + "reference {name}: expected the request's {path:?} ({expected:?}), got {:?}", + s.attr(&root, name) + )); + } + } + AssertionKind::FromServer => {} + } + } + walk_pinned(fields, &root, &mut |f, path| { + let wire = f.wire_name.clone().unwrap_or_else(|| f.name.clone()); + let at = if path.is_empty() { + wire.clone() + } else { + format!("{}/@{wire}", path.join("/")) + }; + match pinned_value(f, &request) { + Some(Err(why)) => out.push(format!("pinned {at}: {why}")), + Some(Ok(value)) => match (s.attr(&path, &wire), pin_is_required(f)) { + // A required pin must be present and exact. + (None, true) => out.push(format!("pinned {at}: required {value:?} not emitted")), + (Some(got), _) if *got != value => { + out.push(format!("pinned {at}: expected {value:?}, emitted {got:?}")) + } + // An optional pin may be absent; it just must not contradict. + _ => {} + }, + None => {} + } + }); + out +} + +/// Whether the pinned attribute must be present. +/// +/// **Not** simply `f.required`. On a [`wa_ir::ParsedFieldType::Bool`] field the pin is +/// always conditional: such a field is a *presence flag* (`{hasListCDhash: m.value != +/// null}`), so `required: true` describes the flag the parser always produces, never the +/// wire attribute it reports on — which may by construction be absent. Treating the flag +/// as the attribute would have this emitter demand an optional `c_dhash` and then compare +/// a request string against a boolean. +fn pin_is_required(f: &ParsedField) -> bool { + f.required && f.field_type != wa_ir::ParsedFieldType::Bool +} + +/// Whether a shape carries any of the constraint layer this guard exists to protect. +fn is_constrained(assertions: &[ResponseAssertion], fields: &[ParsedField]) -> bool { + if assertions + .iter() + .any(|a| a.kind == AssertionKind::Reference) + { + return true; + } + let mut found = false; + walk_pinned(fields, &[], &mut |_, _| found = true); + found +} + +#[test] +fn every_iq_success_variant_round_trips_through_its_own_constraints() { + let path = Path::new(env!("CARGO_MANIFEST_DIR")).join("../../generated/iq/index.json"); + // Committed, so CI always has it: a missing file there means the guard is silently + // not running. Locally (sparse checkout) skip instead of failing spuriously — + // mirroring `wa-proto`'s committed-artifact guard. + if !path.exists() { + assert!( + std::env::var_os("CI").is_none(), + "{} is absent under CI — the IQ round-trip guard would be silently skipped", + path.display() + ); + eprintln!("skipping: {} not present (local only)", path.display()); + return; + } + let raw = std::fs::read_to_string(&path).expect("read generated/iq/index.json"); + let ir: IqIr = serde_json::from_str(&raw).expect("parse the committed IQ IR"); + + let (mut checked, mut constrained, mut pins) = (0usize, 0usize, 0usize); + let mut failures = Vec::new(); + for stanza in &ir.stanzas { + // Both response shapes: a single-shape response's own assertions, and each + // success variant of an outcome union. + let shapes = std::iter::once(( + stanza.response.parser_name.clone(), + &stanza.response.assertions, + &stanza.response.fields, + )) + .chain( + stanza + .response + .variants + .iter() + .filter(|v| v.kind == ResponseVariantKind::Success) + .map(|v| (v.tag.clone(), &v.assertions, &v.fields)), + ); + for (name, assertions, fields) in shapes { + if assertions.is_empty() { + continue; // nothing recorded to satisfy or to check + } + checked += 1; + if is_constrained(assertions, fields) { + constrained += 1; + } + walk_pinned(fields, &[], &mut |_, _| pins += 1); + let node = emit(assertions, fields); + for v in violations(&node, assertions, fields) { + failures.push(format!("{} / {name}: {v}", stanza.module_name)); + } + } + } + + assert!( + checked > 0, + "no IQ response shape carried any assertion — the constraint layer is empty" + ); + // `checked` alone would stay green on a regression that emptied every echo and pin: + // thousands of `assertTag`-only shapes would still be counted. Floor the layer this + // guard actually protects. + assert!( + constrained > 0 && pins > 0, + "{checked} shape(s) carried assertions but only {constrained} carried an echo or a \ + pinned value ({pins} pins total) — the constraint layer degraded to tag-only" + ); + assert!( + failures.is_empty(), + "{} of {checked} IR-built response shape(s) fail their own recorded constraints:\n {}", + failures.len(), + failures.join("\n ") + ); + eprintln!( + "round-tripped {checked} IQ response shape(s) from the IR alone \ + ({constrained} constrained, {pins} pinned field(s) exercised)" + ); +} + +#[test] +fn a_hardcoded_from_fails_the_echo_rule() { + // Negative control: without this the round-trip could pass by vacuously ignoring + // `reference` assertions. Mirrors the real bug — answering a request addressed to + // `g.us` with `from="s.whatsapp.net"`. + let assertions = vec![ + ResponseAssertion { + kind: AssertionKind::Tag, + name: Some("iq".into()), + value: None, + reference_path: None, + }, + ResponseAssertion { + kind: AssertionKind::Reference, + name: Some("from".into()), + value: None, + reference_path: Some(vec!["to".into()]), + }, + ]; + let mut s = emit(&assertions, &[]); + assert!(violations(&s, &assertions, &[]).is_empty()); + s.nodes + .get_mut(&Vec::new()) + .expect("root") + .insert("from".into(), "s.whatsapp.net".to_string()); + let broken = violations(&s, &assertions, &[]); + assert_eq!(broken.len(), 1, "{broken:?}"); + assert!(broken[0].contains("reference from"), "{broken:?}"); +} + +#[test] +fn a_pin_on_a_nested_node_is_checked_where_it_lives() { + // The promote bug in the file header: `type="admin"` sits on ``, not on + // the root. A guard that only modelled the root would accept `` — so assert the nested pin is both emitted and verified at its own + // path, and that a wrong value there is caught. + let participant_type = ParsedField { + method: "attrString".into(), + name: "type".into(), + wire_name: Some("type".into()), + required: true, + literal_value: Some("admin".into()), + ..Default::default() + }; + let fields = vec![ + // `` — a pin reached through a `sourcePath` wrapper. + ParsedField { + method: "attrString".into(), + name: "listMatched".into(), + wire_name: Some("matched".into()), + required: true, + literal_value: Some("true".into()), + source_path: Some(vec!["list".into()]), + ..Default::default() + }, + // `` — a pin inside a nested `child` field. + ParsedField { + method: "child".into(), + name: "promoteParticipant".into(), + tag: Some("participant".into()), + required: true, + children: Some(vec![participant_type]), + ..Default::default() + }, + ]; + let assertions = vec![ResponseAssertion { + kind: AssertionKind::Tag, + name: Some("iq".into()), + value: None, + reference_path: None, + }]; + + let mut s = emit(&assertions, &fields); + assert!( + violations(&s, &assertions, &fields).is_empty(), + "the IR-built stanza must satisfy its own nested pins" + ); + // Both pins really landed on their own nodes, not on the root. + assert_eq!( + s.attr(&["list".to_string()], "matched"), + Some(&"true".to_string()) + ); + assert_eq!( + s.attr(&["participant".to_string()], "type"), + Some(&"admin".to_string()) + ); + assert!(s.attr(&[], "type").is_none(), "must not leak onto the root"); + + // The status-code-where-the-role-goes bug is now caught. + s.nodes + .get_mut(&vec!["participant".to_string()]) + .expect("participant node") + .insert("type".into(), "200".to_string()); + let broken = violations(&s, &assertions, &fields); + assert_eq!(broken.len(), 1, "{broken:?}"); + assert!(broken[0].contains("participant/@type"), "{broken:?}"); +} + +#[test] +fn a_pin_on_a_presence_flag_is_never_required() { + // `{hasListCDhash: m.value != null}` reports whether an OPTIONAL `c_dhash` attribute + // was there; the flag itself is always produced. An emitter must be free to omit the + // attribute — and must never be asked to compare the request's string against the + // boolean. + let flag = ParsedField { + method: String::new(), + name: "hasListCDhash".into(), + wire_name: Some("c_dhash".into()), + field_type: wa_ir::ParsedFieldType::Bool, + required: true, + reference_path: Some(vec!["item".into(), "dhash".into()]), + ..Default::default() + }; + let assertions = vec![ResponseAssertion { + kind: AssertionKind::Tag, + name: Some("iq".into()), + value: None, + reference_path: None, + }]; + let fields = vec![flag]; + let s = emit(&assertions, &fields); + assert!( + s.attr(&[], "c_dhash").is_none(), + "an optional attribute must not be forced onto the stanza" + ); + assert!( + violations(&s, &assertions, &fields).is_empty(), + "omitting it is legal" + ); + // Present but contradicting the request is still caught. + let mut wrong = emit(&assertions, &fields); + wrong + .nodes + .entry(Vec::new()) + .or_default() + .insert("c_dhash".into(), "not-the-request-value".into()); + let broken = violations(&wrong, &assertions, &fields); + assert_eq!(broken.len(), 1, "{broken:?}"); +} + +/// The response shape and the constraint each of the motivating bugs needs. +/// +/// The aggregate floor catches a broad collapse; it cannot catch one variant quietly +/// losing one pin, because the remaining thousands keep the totals healthy. These name +/// the exact constraints whose absence caused a real failure, so losing any one of them +/// fails loudly instead of arithmetically. +const CANARIES: &[(&str, &str, &str)] = &[ + // (variant tag, wire attribute, expected pin) — the successful promote that was + // answered ``. + ("PromoteDemoteResponseSuccessPromote", "type", "admin"), + // The blocklist update answered with a bare ``. + ("UpdateBlockListResponseSuccessWithMatch", "matched", "true"), + ( + "UpdateBlockListResponseSuccessWithMismatch", + "matched", + "false", + ), +]; + +#[test] +fn the_motivating_constraints_are_still_recorded_by_name() { + let path = Path::new(env!("CARGO_MANIFEST_DIR")).join("../../generated/iq/index.json"); + if !path.exists() { + assert!( + std::env::var_os("CI").is_none(), + "{} absent under CI", + path.display() + ); + return; + } + let ir: IqIr = serde_json::from_str(&std::fs::read_to_string(&path).expect("read")) + .expect("parse the committed IQ IR"); + + let variants: Vec<_> = ir + .stanzas + .iter() + .flat_map(|s| &s.response.variants) + .collect(); + for (tag, wire, expected) in CANARIES { + let v = variants + .iter() + .find(|v| &v.tag == tag) + .unwrap_or_else(|| panic!("variant {tag} vanished from the IR")); + let mut found = None; + walk_pinned(&v.fields, &[], &mut |f, _| { + if f.wire_name.as_deref() == Some(*wire) { + found = f.literal_value.clone(); + } + }); + assert_eq!( + found.as_deref(), + Some(*expected), + "{tag}: the pin on `{wire}` is gone — an emitter would be free to send anything there" + ); + } + + // The echo rule, on the variant that made it visible: an error answering a request + // addressed to `g.us` must put that JID in `from`. + let echoes: usize = variants + .iter() + .flat_map(|v| &v.assertions) + .filter(|a| { + a.kind == AssertionKind::Reference + && a.name.as_deref() == Some("from") + && a.reference_path.as_deref() == Some(&["to".to_string()][..]) + }) + .count(); + assert!( + echoes > 100, + "only {echoes} `from` -> request `to` echoes recorded; the rule is collapsing" + ); +} diff --git a/crates/whatspec/src/main.rs b/crates/whatspec/src/main.rs index ee9b7b4..73cccc6 100644 --- a/crates/whatspec/src/main.rs +++ b/crates/whatspec/src/main.rs @@ -748,6 +748,22 @@ struct Counts { /// `manifest.diagnostics.iq.{stanzas,typedResponses}`. iq_stanzas: usize, iq_typed_responses: usize, + /// Validation-constraint coverage, mirroring + /// `manifest.diagnostics.iq.constraints` — see [`IqConstraintCounts`]. + iq_reference_constraints: usize, + iq_field_literals: usize, + iq_field_enum_refs: usize, + iq_typed_error_variants: usize, + iq_error_texts: usize, + iq_error_arms: usize, + /// Notification payload action-union arms recovered (`diagnostics.notif.actions`). + notif_actions: usize, + /// Shape-level coverage of those arms: resolved `actionType`s plus every field, + /// constant and child field across them. The arm COUNT alone cannot regress while + /// the child-tag switch is still recognized — each case still yields one arm even if + /// its whole shape disappeared — so the layer could silently empty out inside a + /// steady count. This is the number that actually moves when extraction breaks. + notif_action_shapes: usize, /// Outgoing non-IQ stanzas (receipt/presence/chatstate/ack) the scanner recovers. stanza_defs: usize, /// Incoming content-stanza read-shapes (message/receipt/call/ack) recovered from @@ -790,6 +806,122 @@ struct IqDiagnostics { /// fields recovered. `requests_enriched`/`fields_recovered` going to 0 flags a /// regression in Phase-2 fragment merging. cross_module: wa_scan::CrossModuleStats, + /// Validation-constraint coverage — see [`IqConstraintCounts`]. + constraints: IqConstraintCounts, +} + +/// How many *validation constraints* the IQ IR carries, counted over the emitted +/// document. These are the numbers the floor guard watches for the constraint layer: +/// each one keys on a distinct JS construct, so a WA refactor that hides one fails +/// loudly instead of silently emptying a field that consumers depend on. +#[derive(Debug, Default, Clone, Copy)] +struct IqConstraintCounts { + /// Echo rules — "this attribute must carry a value taken from the request" — in + /// both forms: `reference` assertions (the required `from` == the request's `to`) + /// and field-level `referencePath` pins (the optional ones). + reference_constraints: usize, + /// `ParsedField`s carrying a pinned `literalValue`. + field_literals: usize, + /// Response fields whose enum argument resolved to a real variant set. + /// Response fields carrying a resolved wire-enum constraint, whether it arrived as a + /// cross-module `enumRef` or an in-module `enumKeys` set. + field_enum_refs: usize, + /// Response variants classified as a client or server error. + typed_error_variants: usize, + /// Text-pinned error arms, keyed by `(module, variant, arm, text)`. + /// + /// NOT the count of distinct texts. A global set of strings cannot fall when one RPC + /// loses its `bad-request` pin while another still carries it — and the arm survives + /// too, so `errorArms` does not move either, and the floor passes while that RPC's + /// accepted `(code, text)` pairing has silently degraded. Counting occurrences is what + /// makes the guard able to see a per-RPC loss. + error_texts: usize, + /// Accepted `(code, text)` error shapes across every RPC — the paired form, which + /// the flattened `errorTexts` count cannot regress on its own. + error_arms: usize, +} + +/// Count the validation constraints in an emitted IQ IR (see [`IqConstraintCounts`]). +fn iq_constraint_counts(ir: &wa_ir::IqIr) -> IqConstraintCounts { + fn walk_fields(fields: &[wa_ir::ParsedField], c: &mut IqConstraintCounts) { + for f in fields { + if f.literal_value.is_some() { + c.field_literals += 1; + } + if f.reference_path.is_some() { + c.reference_constraints += 1; + } + // `enumKeys` is the SAME closed allowed-value constraint, just resolved + // in-module instead of cross-module. Counting only `enumRef` meant losing an + // `enumKeys` table left the floor unmoved — one such field is live today. + if f.enum_ref.is_some() || f.enum_keys.as_ref().is_some_and(|k| !k.is_empty()) { + c.field_enum_refs += 1; + } + if let Some(children) = &f.children { + walk_fields(children, c); + } + for uv in f.union_variants.iter().flatten() { + c.reference_constraints += count_references(&uv.assertions); + walk_fields(&uv.fields, c); + } + } + } + fn count_references(assertions: &[wa_ir::ResponseAssertion]) -> usize { + assertions + .iter() + .filter(|a| a.kind == wa_ir::AssertionKind::Reference) + .count() + } + + let mut c = IqConstraintCounts::default(); + let mut texts = std::collections::BTreeSet::new(); + for s in &ir.stanzas { + c.reference_constraints += count_references(&s.response.assertions); + // `response.fields` is a CLONE of the primary success variant's fields whenever + // `variants` is non-empty (see `response_index::build_pass`), so walking both + // would count that shape's constraints twice — and only for the 97 stanzas that + // have variants, making the inflation non-uniform and the totals simply wrong. + // Walk it directly only for the Pass-2 fallback shape, which has no variants. + if s.response.variants.is_empty() { + walk_fields(&s.response.fields, &mut c); + } + for v in &s.response.variants { + c.reference_constraints += count_references(&v.assertions); + if matches!( + v.kind, + wa_ir::ResponseVariantKind::ClientError | wa_ir::ResponseVariantKind::ServerError + ) { + c.typed_error_variants += 1; + } + // Keyed by the ARM this text pins, not by the text alone. A global set of + // distinct strings cannot fall when one RPC loses its `bad-request` pin while + // another still carries it — and the arm survives too, so `errorArms` does not + // move either, and the floor passes while a specific RPC's accepted + // `(code, text)` pairing silently degrades. + texts.extend( + v.error_arms + .iter() + .chain(v.error_envelope.as_ref()) + .filter(|a| a.text.is_some()) + .map(|a| { + format!( + "{}\u{1}{}\u{1}{}\u{1}{}", + s.module_name, + v.tag, + a.name.as_deref().unwrap_or_default(), + a.text.as_deref().unwrap_or_default() + ) + }), + ); + // Alternatives only. Folding the envelope in made the number disagree with + // the artifact (646 reported against 645 present) and let an envelope + // appearing offset an accepted shape disappearing in the floor check. + c.error_arms += v.error_arms.len(); + walk_fields(&v.fields, &mut c); + } + } + c.error_texts = texts.len(); + c } /// A loaded bundle set: the stamped version, the concatenated source the extractors @@ -1532,10 +1664,18 @@ fn build_artifacts(wa_version: &str, source: &str) -> Result<(Vec, Cou let (abprops_arts, abprops_count) = abprops.expect(checked); let (enums_arts, enums_count) = enums.expect(checked); let (wam_arts, wam_count) = wam.expect(checked); - let (notif_arts, (notif_count, notif_typed, notif_tags)) = notif.expect(checked); + let (notif_arts, notif_counts) = notif.expect(checked); + let NotifCounts { + types: notif_count, + typed_content: notif_typed, + stanza_tags: notif_tags, + actions: notif_actions, + action_shapes: notif_action_shapes, + drops: notif_drops, + } = notif_counts; let (stanza_arts, stanza_count) = stanza.expect(checked); let (tokens_arts, (token_single, token_double)) = tokens.expect(checked); - let (incoming_arts, incoming_count) = incoming.expect(checked); + let (incoming_arts, (incoming_count, incoming_drops)) = incoming.expect(checked); let (srvreq_arts, srvreq_count) = srvreq.expect(checked); let (wasm_arts, (wasm_binaries, wasm_resources, wasm_wasm_handles)) = wasm.expect(checked); @@ -1601,6 +1741,14 @@ fn build_artifacts(wa_version: &str, source: &str) -> Result<(Vec, Cou notif_stanza_tags: notif_tags, iq_stanzas: iq_diag.stanzas, iq_typed_responses: iq_diag.typed_responses, + iq_reference_constraints: iq_diag.constraints.reference_constraints, + iq_field_literals: iq_diag.constraints.field_literals, + iq_field_enum_refs: iq_diag.constraints.field_enum_refs, + iq_typed_error_variants: iq_diag.constraints.typed_error_variants, + iq_error_texts: iq_diag.constraints.error_texts, + iq_error_arms: iq_diag.constraints.error_arms, + notif_actions, + notif_action_shapes, stanza_defs: stanza_count, incoming_defs: incoming_count, server_request_defs: srvreq_count, @@ -1701,13 +1849,28 @@ fn build_artifacts(wa_version: &str, source: &str) -> Result<(Vec, Cou "requestsEnriched": iq_diag.cross_module.requests_enriched, "fieldsRecovered": iq_diag.cross_module.fields_recovered, }, + "constraints": { + "referenceConstraints": iq_diag.constraints.reference_constraints, + "fieldLiterals": iq_diag.constraints.field_literals, + "fieldEnumRefs": iq_diag.constraints.field_enum_refs, + "typedErrorVariants": iq_diag.constraints.typed_error_variants, + "errorTexts": iq_diag.constraints.error_texts, + "errorArms": iq_diag.constraints.error_arms, + }, }, "notif": { "types": counts.notif_types, "typedContent": counts.notif_typed_content, "degraded": counts.notif_types - counts.notif_typed_content, "stanzaTags": counts.notif_stanza_tags, + "actions": counts.notif_actions, + "actionShapes": counts.notif_action_shapes, + "dropsByReason": notif_drops, }, + // These two domains run the same legacy parser as IQ and had no diagnostics + // block at all, so a constraint they saw and could not recover was reported + // nowhere — the one case the pending marker cannot distinguish on its own. + "incoming": { "dropsByReason": incoming_drops }, }, }); artifacts.push(Artifact { @@ -1776,6 +1939,26 @@ fn check_floor(out: &Path, counts: &Counts) -> Result> { regressions.push(format!("iq.{key}: {prev} → {new}")); } } + // The validation-constraint layer. Each counter keys on a distinct JS construct + // (`attrStringFromReference`, `literal`/`optionalLiteral`, the enum accessors, + // the error mixins), so a WA refactor that hides one shows up here rather than + // as a silently emptier field in every consumer's copy of the IR. + if let Some(c) = iq.get("constraints") { + for (key, new) in [ + ("referenceConstraints", counts.iq_reference_constraints), + ("fieldLiterals", counts.iq_field_literals), + ("fieldEnumRefs", counts.iq_field_enum_refs), + ("typedErrorVariants", counts.iq_typed_error_variants), + ("errorTexts", counts.iq_error_texts), + ("errorArms", counts.iq_error_arms), + ] { + if let Some(prev) = c.get(key).and_then(serde_json::Value::as_u64) + && (new as u64) < prev + { + regressions.push(format!("iq.constraints.{key}: {prev} → {new}")); + } + } + } } // Notification coverage below the catalog count: a drop in typed-content means a // handler's parser stopped resolving; a drop in stanzaTags means the tag-switch @@ -1784,6 +1967,8 @@ fn check_floor(out: &Path, counts: &Counts) -> Result> { for (key, new) in [ ("typedContent", counts.notif_typed_content), ("stanzaTags", counts.notif_stanza_tags), + ("actions", counts.notif_actions), + ("actionShapes", counts.notif_action_shapes), ] { if let Some(prev) = notif.get(key).and_then(serde_json::Value::as_u64) && (new as u64) < prev @@ -1849,6 +2034,17 @@ fn push_stanza( Ok(count) } +/// What the notification pass reports back: the counters the floor guard watches plus +/// the constraints it saw and could not resolve. +struct NotifCounts { + types: usize, + typed_content: usize, + stanza_tags: usize, + actions: usize, + action_shapes: usize, + drops: std::collections::BTreeMap, +} + /// Emit the incoming content-stanza read-shape catalog (`incoming/index.json`) — the /// field trees WA Web parses out of received message/receipt/call/ack stanzas. Neutral /// IR only; the codegen is a later phase. @@ -1857,17 +2053,18 @@ fn push_incoming( wa_version: &str, source: &str, module_defs: &[wa_transform::ModuleDefinition], -) -> Result { +) -> Result<(usize, std::collections::BTreeMap)> { + let (incoming, drops) = wa_scan::scan_incoming_with_diagnostics(source, module_defs); let ir = wa_ir::IncomingIr { wa_version: wa_version.to_string(), - incoming: wa_scan::scan_incoming_from_modules(source, module_defs), + incoming, }; let count = ir.incoming.len(); artifacts.push(Artifact { rel_path: PathBuf::from("incoming/index.json"), content: serde_json::to_string_pretty(&wa_ir::IrEnvelope::new(&ir))? + "\n", }); - Ok(count) + Ok((count, drops)) } /// Emit the server-initiated request read-shape catalog (`srvreq/index.json`) — the @@ -1927,8 +2124,9 @@ fn push_iq( source: &str, module_defs: &[wa_transform::ModuleDefinition], ) -> Result<(usize, IqDiagnostics)> { - let (ir, cross_module) = + let (ir, scan_stats) = wa_scan::extract_iq_from_modules_with_diagnostics(source, module_defs, wa_version); + let cross_module = scan_stats.cross_module; // M8/M9 diagnostics. Every IQ candidate module yields ≥1 stanza or exactly one // `unparseable` entry, so the candidate count is the number of distinct @@ -1976,6 +2174,12 @@ fn push_iq( for u in &ir.unparseable { *drops_by_reason.entry(u.reason.clone()).or_default() += 1; } + // Constraints the response analysis saw but could not resolve structurally. Recorded + // here rather than dropped silently: a consumer must be able to tell "this field has + // no pinned value" from "this field has one and we failed to extract it". + for (reason, n) in &scan_stats.constraint_drops { + *drops_by_reason.entry(reason.clone()).or_default() += n; + } eprintln!( "iq: cross-module fragments -> {} request(s) reference mixins, {} enriched, \ {} field(s) recovered", @@ -1992,6 +2196,7 @@ fn push_iq( excluded_fragments: fragments, drops_by_reason, cross_module, + constraints: iq_constraint_counts(&ir), }; // Neutral, language-agnostic IR (the cross-language contract): the same @@ -2121,8 +2326,9 @@ fn push_notif( wa_version: &str, source: &str, module_defs: &[wa_transform::ModuleDefinition], -) -> Result<(usize, usize, usize)> { - let ir = wa_notif::extract_notif_from_modules(source, module_defs, wa_version); +) -> Result { + let (ir, notif_drops) = + wa_notif::extract_notif_with_diagnostics(source, module_defs, wa_version); let count = ir.notifications.len(); let stanza_tags = ir.stanza_tags.len(); let typed = ir @@ -2130,8 +2336,23 @@ fn push_notif( .iter() .filter(|n| n.content.is_some()) .count(); + // Payload action-union arms (the `w:gp2` group actions and friends) — the layer + // below the envelope, counted so it can't silently empty out. + let actions: usize = ir.notifications.iter().map(|n| n.actions.len()).sum(); + let action_shapes: usize = ir + .notifications + .iter() + .flat_map(|n| &n.actions) + .map(|a| { + usize::from(a.action_type.is_some()) + + a.fields.len() + + a.constant_fields.len() + + a.children.iter().map(|c| 1 + c.fields.len()).sum::() + }) + .sum(); eprintln!( "notif: {count} notification types ({typed} with typed content, {} degraded), \ + {actions} payload action(s) / {action_shapes} shape element(s), \ {} stanza tags (dispatchers: {})", count - typed, stanza_tags, @@ -2151,7 +2372,14 @@ fn push_notif( rel_path: PathBuf::from("notif/notif.rs"), content: wa_codegen::generate_notif(&ir), }); - Ok((count, typed, stanza_tags)) + Ok(NotifCounts { + types: count, + typed_content: typed, + stanza_tags, + actions, + action_shapes, + drops: notif_drops, + }) } fn push_wam( @@ -2473,6 +2701,7 @@ mod tests { wasm_binaries: 0, wasm_resources: 0, wasm_wasm_handles: 0, + ..Default::default() }; let regressions = check_floor(&dir, &counts).unwrap(); assert_eq!(regressions.len(), 2); diff --git a/generated/abprops/index.json b/generated/abprops/index.json index 21609ec..cd26ba2 100644 --- a/generated/abprops/index.json +++ b/generated/abprops/index.json @@ -1,5 +1,5 @@ { - "schemaVersion": "1.0.0", + "schemaVersion": "2.0.0", "waVersion": "2.3000.1043899084", "configs": [ { diff --git a/generated/appstate/index.json b/generated/appstate/index.json index 066d2d9..42f57b2 100644 --- a/generated/appstate/index.json +++ b/generated/appstate/index.json @@ -1,5 +1,5 @@ { - "schemaVersion": "1.0.0", + "schemaVersion": "2.0.0", "waVersion": "2.3000.1043899084", "collections": [ "regular", diff --git a/generated/enums/index.json b/generated/enums/index.json index 8a66ae9..836f903 100644 --- a/generated/enums/index.json +++ b/generated/enums/index.json @@ -1,5 +1,5 @@ { - "schemaVersion": "1.0.0", + "schemaVersion": "2.0.0", "waVersion": "2.3000.1043899084", "enums": [ { diff --git a/generated/incoming/index.json b/generated/incoming/index.json index 03459cd..c6ec76d 100644 --- a/generated/incoming/index.json +++ b/generated/incoming/index.json @@ -1,5 +1,5 @@ { - "schemaVersion": "1.0.0", + "schemaVersion": "2.0.0", "waVersion": "2.3000.1043899084", "incoming": [ { @@ -25,8 +25,30 @@ { "method": "attrEnumValues", "name": "type", - "type": "string", - "required": true + "type": "enum", + "required": true, + "enumRef": { + "name": "CiphertextType", + "module": "WAWebBackendJobs.flow", + "variants": [ + { + "name": "Skmsg", + "value": "skmsg" + }, + { + "name": "Pkmsg", + "value": "pkmsg" + }, + { + "name": "Msg", + "value": "msg" + }, + { + "name": "Msmsg", + "value": "msmsg" + } + ] + } }, { "method": "maybeAttrString", @@ -106,8 +128,42 @@ { "method": "attrEnum", "name": "type", - "type": "string", - "required": true + "type": "enum", + "required": true, + "enumRef": { + "name": "STANZA_MSG_TYPES", + "module": "WAWebHandleMsgCommon", + "variants": [ + { + "name": "text", + "value": "text" + }, + { + "name": "media", + "value": "media" + }, + { + "name": "medianotify", + "value": "medianotify" + }, + { + "name": "pay", + "value": "pay" + }, + { + "name": "poll", + "value": "poll" + }, + { + "name": "reaction", + "value": "reaction" + }, + { + "name": "event", + "value": "event" + } + ] + } }, { "method": "attrString", @@ -224,9 +280,9 @@ "required": false }, { - "method": "maybeAttrString", + "method": "maybeAttrEnum", "name": "type", - "type": "string", + "type": "enum", "required": false, "enumKeys": [ "delivery", @@ -296,8 +352,19 @@ { "method": "maybeAttrEnum", "name": "type", - "type": "string", - "required": false + "type": "enum", + "required": false, + "enumKeys": [ + "delivery", + "read", + "played", + "inactive", + "server-error", + "sender", + "read-self", + "played-self", + "peer_msg" + ] }, { "method": "attrUserJid", @@ -418,6 +485,22 @@ } ] }, + { + "method": "child", + "name": "id", + "type": "string", + "required": true, + "tag": "id", + "children": [ + { + "method": "contentUint", + "name": "content", + "type": "integer", + "required": true, + "byteLength": 3 + } + ] + }, { "method": "child", "name": "value", @@ -468,7 +551,15 @@ "type": "string", "required": true, "tag": "registration", - "children": [] + "children": [ + { + "method": "contentUint", + "name": "content", + "type": "integer", + "required": true, + "byteLength": 4 + } + ] } ] } @@ -720,10 +811,24 @@ "kind": "tag", "name": "ack" }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "class", "value": "message" + }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] } ], "fields": [ @@ -739,7 +844,8 @@ "name": "class", "wireName": "class", "type": "string", - "required": true + "required": true, + "literalValue": "message" }, { "method": "attrInt", @@ -759,7 +865,8 @@ "name": "edit", "wireName": "edit", "type": "string", - "required": true + "required": true, + "literalValue": "1" } ], "sameNode": true @@ -775,7 +882,8 @@ "name": "edit", "wireName": "edit", "type": "string", - "required": true + "required": true, + "literalValue": "3" } ], "sameNode": true @@ -791,7 +899,8 @@ "name": "edit", "wireName": "edit", "type": "string", - "required": true + "required": true, + "literalValue": "2" } ], "sameNode": true @@ -807,7 +916,8 @@ "name": "edit", "wireName": "edit", "type": "string", - "required": true + "required": true, + "literalValue": "8" } ], "sameNode": true @@ -823,7 +933,8 @@ "name": "edit", "wireName": "edit", "type": "string", - "required": true + "required": true, + "literalValue": "7" } ], "sameNode": true @@ -874,6 +985,24 @@ "wireName": "pricing_model", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_CBP_NBP_PMP", + "module": "WASmaxInMessagePublishEnums", + "variants": [ + { + "name": "CBP", + "value": "CBP" + }, + { + "name": "NBP", + "value": "NBP" + }, + { + "name": "PMP", + "value": "PMP" + } + ] + }, "sourcePath": [ "biz" ] @@ -884,6 +1013,20 @@ "wireName": "billable", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInMessagePublishEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + }, "sourcePath": [ "biz" ] @@ -914,6 +1057,24 @@ "wireName": "pricing_type", "type": "enum", "required": false, + "enumRef": { + "name": "ENUM_FREECUSTOMERSERVICE_FREEENTRYPOINT_REGULAR", + "module": "WASmaxInMessagePublishEnums", + "variants": [ + { + "name": "free_customer_service", + "value": "free_customer_service" + }, + { + "name": "free_entry_point", + "value": "free_entry_point" + }, + { + "name": "regular", + "value": "regular" + } + ] + }, "sourcePath": [ "biz" ] @@ -930,7 +1091,21 @@ "name": "optimizationGoal", "wireName": "optimization_goal", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_DELIVERY_NOOPTIMIZATION", + "module": "WASmaxInMessagePublishEnums", + "variants": [ + { + "name": "delivery", + "value": "delivery" + }, + { + "name": "no_optimization", + "value": "no_optimization" + } + ] + } } ], "repeats": false, @@ -1148,7 +1323,8 @@ "name": "class", "wireName": "class", "type": "string", - "required": true + "required": true, + "literalValue": "message" }, { "method": "attrInt", @@ -1168,7 +1344,8 @@ "name": "edit", "wireName": "edit", "type": "string", - "required": true + "required": true, + "literalValue": "1" } ], "sameNode": true @@ -1184,7 +1361,8 @@ "name": "edit", "wireName": "edit", "type": "string", - "required": true + "required": true, + "literalValue": "3" } ], "sameNode": true @@ -1200,7 +1378,8 @@ "name": "edit", "wireName": "edit", "type": "string", - "required": true + "required": true, + "literalValue": "2" } ], "sameNode": true @@ -1216,7 +1395,8 @@ "name": "edit", "wireName": "edit", "type": "string", - "required": true + "required": true, + "literalValue": "8" } ], "sameNode": true @@ -1232,7 +1412,8 @@ "name": "edit", "wireName": "edit", "type": "string", - "required": true + "required": true, + "literalValue": "7" } ], "sameNode": true @@ -1283,6 +1464,24 @@ "wireName": "pricing_model", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_CBP_NBP_PMP", + "module": "WASmaxInMessagePublishEnums", + "variants": [ + { + "name": "CBP", + "value": "CBP" + }, + { + "name": "NBP", + "value": "NBP" + }, + { + "name": "PMP", + "value": "PMP" + } + ] + }, "sourcePath": [ "biz" ] @@ -1293,6 +1492,20 @@ "wireName": "billable", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInMessagePublishEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + }, "sourcePath": [ "biz" ] @@ -1323,6 +1536,24 @@ "wireName": "pricing_type", "type": "enum", "required": false, + "enumRef": { + "name": "ENUM_FREECUSTOMERSERVICE_FREEENTRYPOINT_REGULAR", + "module": "WASmaxInMessagePublishEnums", + "variants": [ + { + "name": "free_customer_service", + "value": "free_customer_service" + }, + { + "name": "free_entry_point", + "value": "free_entry_point" + }, + { + "name": "regular", + "value": "regular" + } + ] + }, "sourcePath": [ "biz" ] @@ -1339,7 +1570,21 @@ "name": "optimizationGoal", "wireName": "optimization_goal", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_DELIVERY_NOOPTIMIZATION", + "module": "WASmaxInMessagePublishEnums", + "variants": [ + { + "name": "delivery", + "value": "delivery" + }, + { + "name": "no_optimization", + "value": "no_optimization" + } + ] + } } ], "repeats": false, @@ -1493,10 +1738,24 @@ "kind": "tag", "name": "ack" }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "class", "value": "message" + }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] } ] }, @@ -1517,7 +1776,8 @@ "name": "class", "wireName": "class", "type": "string", - "required": true + "required": true, + "literalValue": "message" }, { "method": "attrInt", @@ -1537,7 +1797,8 @@ "name": "edit", "wireName": "edit", "type": "string", - "required": true + "required": true, + "literalValue": "1" } ], "sameNode": true @@ -1553,7 +1814,8 @@ "name": "edit", "wireName": "edit", "type": "string", - "required": true + "required": true, + "literalValue": "3" } ], "sameNode": true @@ -1569,7 +1831,8 @@ "name": "edit", "wireName": "edit", "type": "string", - "required": true + "required": true, + "literalValue": "2" } ], "sameNode": true @@ -1585,7 +1848,8 @@ "name": "edit", "wireName": "edit", "type": "string", - "required": true + "required": true, + "literalValue": "8" } ], "sameNode": true @@ -1601,7 +1865,8 @@ "name": "edit", "wireName": "edit", "type": "string", - "required": true + "required": true, + "literalValue": "7" } ], "sameNode": true @@ -1652,6 +1917,24 @@ "wireName": "pricing_model", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_CBP_NBP_PMP", + "module": "WASmaxInMessagePublishEnums", + "variants": [ + { + "name": "CBP", + "value": "CBP" + }, + { + "name": "NBP", + "value": "NBP" + }, + { + "name": "PMP", + "value": "PMP" + } + ] + }, "sourcePath": [ "biz" ] @@ -1662,6 +1945,20 @@ "wireName": "billable", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInMessagePublishEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + }, "sourcePath": [ "biz" ] @@ -1692,6 +1989,24 @@ "wireName": "pricing_type", "type": "enum", "required": false, + "enumRef": { + "name": "ENUM_FREECUSTOMERSERVICE_FREEENTRYPOINT_REGULAR", + "module": "WASmaxInMessagePublishEnums", + "variants": [ + { + "name": "free_customer_service", + "value": "free_customer_service" + }, + { + "name": "free_entry_point", + "value": "free_entry_point" + }, + { + "name": "regular", + "value": "regular" + } + ] + }, "sourcePath": [ "biz" ] @@ -1708,7 +2023,21 @@ "name": "optimizationGoal", "wireName": "optimization_goal", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_DELIVERY_NOOPTIMIZATION", + "module": "WASmaxInMessagePublishEnums", + "variants": [ + { + "name": "delivery", + "value": "delivery" + }, + { + "name": "no_optimization", + "value": "no_optimization" + } + ] + } } ], "repeats": false, @@ -1880,10 +2209,24 @@ "kind": "tag", "name": "ack" }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "class", "value": "message" + }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] } ] } @@ -1902,10 +2245,24 @@ "kind": "tag", "name": "ack" }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "class", "value": "status" + }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] } ], "fields": [ @@ -1921,7 +2278,8 @@ "name": "class", "wireName": "class", "type": "string", - "required": true + "required": true, + "literalValue": "status" }, { "method": "attrInt", @@ -1944,7 +2302,8 @@ "name": "edit", "wireName": "edit", "type": "string", - "required": true + "required": true, + "literalValue": "1" } ], "assertions": [ @@ -1967,7 +2326,8 @@ "name": "edit", "wireName": "edit", "type": "string", - "required": true + "required": true, + "literalValue": "7" } ], "assertions": [ @@ -1990,7 +2350,8 @@ "name": "edit", "wireName": "edit", "type": "string", - "required": true + "required": true, + "literalValue": "8" } ], "assertions": [ @@ -2054,10 +2415,24 @@ "kind": "tag", "name": "ack" }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "class", "value": "status" + }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] } ], "fields": [ @@ -2075,7 +2450,8 @@ "name": "class", "wireName": "class", "type": "string", - "required": true + "required": true, + "literalValue": "status" }, { "method": "attrInt", @@ -2098,7 +2474,8 @@ "name": "edit", "wireName": "edit", "type": "string", - "required": true + "required": true, + "literalValue": "1" } ], "assertions": [ @@ -2121,7 +2498,8 @@ "name": "edit", "wireName": "edit", "type": "string", - "required": true + "required": true, + "literalValue": "7" } ], "assertions": [ @@ -2144,7 +2522,8 @@ "name": "edit", "wireName": "edit", "type": "string", - "required": true + "required": true, + "literalValue": "8" } ], "assertions": [ @@ -2174,10 +2553,31 @@ "kind": "tag", "name": "ack" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, { "kind": "attr", "name": "class", "value": "receipt" + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, + { + "kind": "reference", + "name": "type", + "referencePath": [ + "type" + ] } ], "fields": [ @@ -2186,7 +2586,8 @@ "name": "class", "wireName": "class", "type": "string", - "required": true + "required": true, + "literalValue": "receipt" }, { "method": "maybeAttrInt", @@ -2200,7 +2601,21 @@ "name": "readreceipts", "wireName": "readreceipts", "type": "enum", - "required": false + "required": false, + "enumRef": { + "name": "ENUM_ALL_NONE", + "module": "WASmaxInReceiptEnums", + "variants": [ + { + "name": "all", + "value": "all" + }, + { + "name": "none", + "value": "none" + } + ] + } }, { "method": "", @@ -2236,8 +2651,22 @@ { "method": "attrEnum", "name": "readreceipts", - "type": "string", - "required": true + "type": "enum", + "required": true, + "enumRef": { + "name": "ALL_NONE", + "module": "WAWebPrivacySettings", + "variants": [ + { + "name": "all", + "value": "all" + }, + { + "name": "none", + "value": "none" + } + ] + } } ] } diff --git a/generated/iq/index.json b/generated/iq/index.json index d7c8a1a..92e3e9f 100644 --- a/generated/iq/index.json +++ b/generated/iq/index.json @@ -1,5 +1,5 @@ { - "schemaVersion": "1.0.0", + "schemaVersion": "2.0.0", "waVersion": "2.3000.1043899084", "stanzas": [ { @@ -52,6 +52,7 @@ "wireName": "protocol", "type": "string", "required": true, + "literalValue": "1", "sourcePath": [ "props" ] @@ -102,6 +103,20 @@ "wireName": "delta_update", "type": "enum", "required": false, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInAbPropsEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + }, "sourcePath": [ "props" ] @@ -111,7 +126,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "child", @@ -222,6 +238,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -235,6 +265,7 @@ "wireName": "protocol", "type": "string", "required": true, + "literalValue": "1", "sourcePath": [ "props" ] @@ -285,6 +316,20 @@ "wireName": "delta_update", "type": "enum", "required": false, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInAbPropsEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + }, "sourcePath": [ "props" ] @@ -294,7 +339,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "child", @@ -400,11 +446,37 @@ "tag": "GetExperimentConfigResponseErrorNoRetry", "moduleName": "WASmaxInAbPropsGetExperimentConfigResponseErrorNoRetry", "kind": "error", + "errorArms": [ + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorFeatureNotImplemented", + "code": 501, + "text": "feature-not-implemented" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -417,7 +489,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -433,14 +506,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -452,6 +527,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -463,14 +543,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "feature-not-implemented" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "501" } ], "assertions": [ @@ -482,6 +564,11 @@ "kind": "attr", "name": "text", "value": "feature-not-implemented" + }, + { + "kind": "attr", + "name": "code", + "value": "501" } ] } @@ -495,12 +582,32 @@ { "tag": "GetExperimentConfigResponseErrorRetry", "moduleName": "WASmaxInAbPropsGetExperimentConfigResponseErrorRetry", - "kind": "error", + "kind": "server_error", + "errorArms": [ + { + "code": 500, + "text": "internal-server-error" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -520,14 +627,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "repeats": false @@ -537,7 +646,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ] } @@ -627,7 +737,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "child", @@ -720,6 +831,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -772,7 +897,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "child", @@ -860,11 +986,37 @@ "tag": "GetGroupExperimentConfigResponseErrorNoRetry", "moduleName": "WASmaxInAbPropsGetGroupExperimentConfigResponseErrorNoRetry", "kind": "error", + "errorArms": [ + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorFeatureNotImplemented", + "code": 501, + "text": "feature-not-implemented" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -877,7 +1029,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -893,14 +1046,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -912,6 +1067,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -923,14 +1083,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "feature-not-implemented" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "501" } ], "assertions": [ @@ -942,6 +1104,11 @@ "kind": "attr", "name": "text", "value": "feature-not-implemented" + }, + { + "kind": "attr", + "name": "code", + "value": "501" } ] } @@ -955,12 +1122,32 @@ { "tag": "GetGroupExperimentConfigResponseErrorRetry", "moduleName": "WASmaxInAbPropsGetGroupExperimentConfigResponseErrorRetry", - "kind": "error", + "kind": "server_error", + "errorArms": [ + { + "code": 500, + "text": "internal-server-error" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -980,14 +1167,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "repeats": false @@ -997,7 +1186,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ] } @@ -1043,7 +1233,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "maybeAttrString", @@ -1061,6 +1252,7 @@ "wireName": "addressing_mode", "type": "string", "required": false, + "literalValue": "pn", "sourcePath": [ "list" ] @@ -1119,10 +1311,24 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", "value": "result" + }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] } ], "fields": [ @@ -1131,7 +1337,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "maybeAttrString", @@ -1149,6 +1356,7 @@ "wireName": "addressing_mode", "type": "string", "required": false, + "literalValue": "pn", "sourcePath": [ "list" ] @@ -1207,10 +1415,24 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", "value": "result" + }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] } ], "fields": [ @@ -1219,7 +1441,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "maybeAttrString", @@ -1237,6 +1460,7 @@ "wireName": "addressing_mode", "type": "string", "required": true, + "literalValue": "lid", "sourcePath": [ "list" ] @@ -1260,7 +1484,8 @@ "name": "active", "wireName": "active", "type": "string", - "required": false + "required": false, + "literalValue": "true" }, { "method": "maybeAttrString", @@ -1350,7 +1575,8 @@ "name": "unknownIdentifier", "wireName": "unknown_identifier", "type": "string", - "required": true + "required": true, + "literalValue": "true" } ], "assertions": [ @@ -1380,10 +1606,24 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", "value": "result" + }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] } ], "fields": [ @@ -1392,7 +1632,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "maybeAttrString", @@ -1410,6 +1651,7 @@ "wireName": "addressing_mode", "type": "string", "required": true, + "literalValue": "lid", "sourcePath": [ "list" ] @@ -1420,6 +1662,7 @@ "wireName": "dirty", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "list" ] @@ -1443,7 +1686,8 @@ "name": "active", "wireName": "active", "type": "string", - "required": false + "required": false, + "literalValue": "true" }, { "method": "maybeAttrString", @@ -1533,7 +1777,8 @@ "name": "unknownIdentifier", "wireName": "unknown_identifier", "type": "string", - "required": true + "required": true, + "literalValue": "true" } ], "assertions": [ @@ -1563,10 +1808,24 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", "value": "result" + }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] } ], "fields": [ @@ -1575,7 +1834,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "maybeAttrString", @@ -1593,6 +1853,7 @@ "wireName": "addressing_mode", "type": "string", "required": true, + "literalValue": "lid", "sourcePath": [ "list" ] @@ -1616,7 +1877,8 @@ "name": "active", "wireName": "active", "type": "string", - "required": false + "required": false, + "literalValue": "true" }, { "method": "maybeAttrString", @@ -1706,7 +1968,8 @@ "name": "unknownIdentifier", "wireName": "unknown_identifier", "type": "string", - "required": true + "required": true, + "literalValue": "true" } ], "assertions": [ @@ -1736,10 +1999,24 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", "value": "result" + }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] } ], "fields": [ @@ -1748,19 +2025,46 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ] }, { "tag": "GetBlockListResponseInvalidRequest", "moduleName": "WASmaxInBlocklistsGetBlockListResponseInvalidRequest", - "kind": "error", + "kind": "client_error", + "errorArms": [ + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorRateOverlimit", + "code": 429, + "text": "rate-overlimit" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -1773,7 +2077,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -1789,14 +2094,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -1808,6 +2115,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -1819,14 +2131,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "rate-overlimit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "429" } ], "assertions": [ @@ -1838,6 +2152,11 @@ "kind": "attr", "name": "text", "value": "rate-overlimit" + }, + { + "kind": "attr", + "name": "code", + "value": "429" } ] } @@ -1851,12 +2170,38 @@ { "tag": "GetBlockListResponseInternalServerError", "moduleName": "WASmaxInBlocklistsGetBlockListResponseInternalServerError", - "kind": "error", + "kind": "server_error", + "errorArms": [ + { + "name": "IQErrorFeatureNotImplemented", + "code": 501, + "text": "feature-not-implemented" + }, + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -1869,7 +2214,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -1885,14 +2231,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "feature-not-implemented" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "501" } ], "assertions": [ @@ -1904,6 +2252,11 @@ "kind": "attr", "name": "text", "value": "feature-not-implemented" + }, + { + "kind": "attr", + "name": "code", + "value": "501" } ] }, @@ -1915,14 +2268,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -1934,6 +2289,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] } @@ -2029,7 +2389,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "attrString", @@ -2037,6 +2398,7 @@ "wireName": "matched", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "list" ] @@ -2062,10 +2424,24 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", "value": "result" + }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] } ], "fields": [ @@ -2074,7 +2450,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "attrString", @@ -2082,6 +2459,7 @@ "wireName": "matched", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "list" ] @@ -2107,10 +2485,24 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", "value": "result" + }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] } ], "fields": [ @@ -2119,7 +2511,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "attrString", @@ -2127,6 +2520,7 @@ "wireName": "matched", "type": "string", "required": true, + "literalValue": "false", "sourcePath": [ "list" ] @@ -2136,7 +2530,14 @@ "name": "hasListCDhash", "wireName": "c_dhash", "type": "bool", - "required": true + "required": true, + "referencePath": [ + "item", + "dhash" + ], + "sourcePath": [ + "list" + ] }, { "method": "attrString", @@ -2154,6 +2555,7 @@ "wireName": "addressing_mode", "type": "string", "required": false, + "literalValue": "pn", "sourcePath": [ "list" ] @@ -2205,10 +2607,24 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", "value": "result" + }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] } ], "fields": [ @@ -2217,7 +2633,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "attrString", @@ -2225,6 +2642,7 @@ "wireName": "matched", "type": "string", "required": true, + "literalValue": "false", "sourcePath": [ "list" ] @@ -2234,7 +2652,14 @@ "name": "hasListCDhash", "wireName": "c_dhash", "type": "bool", - "required": true + "required": true, + "referencePath": [ + "item", + "dhash" + ], + "sourcePath": [ + "list" + ] }, { "method": "attrString", @@ -2252,6 +2677,7 @@ "wireName": "addressing_mode", "type": "string", "required": true, + "literalValue": "lid", "sourcePath": [ "list" ] @@ -2275,7 +2701,8 @@ "name": "active", "wireName": "active", "type": "string", - "required": false + "required": false, + "literalValue": "true" }, { "method": "maybeAttrString", @@ -2365,7 +2792,8 @@ "name": "unknownIdentifier", "wireName": "unknown_identifier", "type": "string", - "required": true + "required": true, + "literalValue": "true" } ], "assertions": [ @@ -2395,10 +2823,24 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", "value": "result" + }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] } ], "fields": [ @@ -2407,7 +2849,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "attrString", @@ -2415,6 +2858,7 @@ "wireName": "matched", "type": "string", "required": true, + "literalValue": "false", "sourcePath": [ "list" ] @@ -2424,7 +2868,14 @@ "name": "hasListCDhash", "wireName": "c_dhash", "type": "bool", - "required": true + "required": true, + "referencePath": [ + "item", + "dhash" + ], + "sourcePath": [ + "list" + ] }, { "method": "attrString", @@ -2442,6 +2893,7 @@ "wireName": "addressing_mode", "type": "string", "required": true, + "literalValue": "lid", "sourcePath": [ "list" ] @@ -2465,7 +2917,8 @@ "name": "active", "wireName": "active", "type": "string", - "required": false + "required": false, + "literalValue": "true" }, { "method": "maybeAttrString", @@ -2555,7 +3008,8 @@ "name": "unknownIdentifier", "wireName": "unknown_identifier", "type": "string", - "required": true + "required": true, + "literalValue": "true" } ], "assertions": [ @@ -2579,12 +3033,53 @@ { "tag": "UpdateBlockListResponseInvalidRequest", "moduleName": "WASmaxInBlocklistsUpdateBlockListResponseInvalidRequest", - "kind": "error", + "kind": "client_error", + "errorArms": [ + { + "name": "IQErrorNotAcceptable", + "code": 406, + "text": "not-acceptable" + }, + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorForbidden", + "code": 403, + "text": "forbidden" + }, + { + "name": "IQErrorRateOverlimit", + "code": 429, + "text": "rate-overlimit" + }, + { + "name": "IQErrorNotAllowed", + "code": 405, + "text": "not-allowed" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -2598,6 +3093,20 @@ "wireName": "addressing_mode", "type": "enum", "required": false, + "enumRef": { + "name": "ENUM_LID_PN", + "module": "WASmaxInBlocklistsEnums", + "variants": [ + { + "name": "lid", + "value": "lid" + }, + { + "name": "pn", + "value": "pn" + } + ] + }, "sourcePath": [ "error" ] @@ -2607,7 +3116,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -2623,14 +3133,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-acceptable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "406" }, { "method": "child", @@ -2666,6 +3178,11 @@ "kind": "attr", "name": "text", "value": "not-acceptable" + }, + { + "kind": "attr", + "name": "code", + "value": "406" } ] }, @@ -2677,14 +3194,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -2696,6 +3215,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -2707,14 +3231,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "forbidden" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "403" } ], "assertions": [ @@ -2726,6 +3252,11 @@ "kind": "attr", "name": "text", "value": "forbidden" + }, + { + "kind": "attr", + "name": "code", + "value": "403" } ] }, @@ -2737,14 +3268,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "rate-overlimit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "429" } ], "assertions": [ @@ -2756,6 +3289,11 @@ "kind": "attr", "name": "text", "value": "rate-overlimit" + }, + { + "kind": "attr", + "name": "code", + "value": "429" } ] }, @@ -2767,14 +3305,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-allowed" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "405" } ], "assertions": [ @@ -2786,6 +3326,11 @@ "kind": "attr", "name": "text", "value": "not-allowed" + }, + { + "kind": "attr", + "name": "code", + "value": "405" } ] } @@ -2799,12 +3344,38 @@ { "tag": "UpdateBlockListResponseServerError", "moduleName": "WASmaxInBlocklistsUpdateBlockListResponseServerError", - "kind": "error", + "kind": "server_error", + "errorArms": [ + { + "name": "IQErrorFeatureNotImplemented", + "code": 501, + "text": "feature-not-implemented" + }, + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -2817,7 +3388,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -2833,14 +3405,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "feature-not-implemented" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "501" } ], "assertions": [ @@ -2852,6 +3426,11 @@ "kind": "attr", "name": "text", "value": "feature-not-implemented" + }, + { + "kind": "attr", + "name": "code", + "value": "501" } ] }, @@ -2863,14 +3442,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -2882,6 +3463,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] } @@ -2953,6 +3539,7 @@ "wireName": "v", "type": "string", "required": true, + "literalValue": "2", "sourcePath": [ "bot" ] @@ -2984,7 +3571,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "child", @@ -3005,7 +3593,25 @@ "name": "type", "wireName": "type", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_ALL_CATEGORY_FEATURED", + "module": "WASmaxInBotEnums", + "variants": [ + { + "name": "all", + "value": "all" + }, + { + "name": "category", + "value": "category" + }, + { + "name": "featured", + "value": "featured" + } + ] + } }, { "method": "child", @@ -3047,7 +3653,21 @@ "name": "mode", "wireName": "mode", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_DARK_LIGHT", + "module": "WASmaxInBotEnums", + "variants": [ + { + "name": "dark", + "value": "dark" + }, + { + "name": "light", + "value": "light" + } + ] + } }, { "method": "contentString", @@ -3099,6 +3719,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -3112,6 +3746,7 @@ "wireName": "v", "type": "string", "required": true, + "literalValue": "2", "sourcePath": [ "bot" ] @@ -3143,7 +3778,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "child", @@ -3164,7 +3800,25 @@ "name": "type", "wireName": "type", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_ALL_CATEGORY_FEATURED", + "module": "WASmaxInBotEnums", + "variants": [ + { + "name": "all", + "value": "all" + }, + { + "name": "category", + "value": "category" + }, + { + "name": "featured", + "value": "featured" + } + ] + } }, { "method": "child", @@ -3206,7 +3860,21 @@ "name": "mode", "wireName": "mode", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_DARK_LIGHT", + "module": "WASmaxInBotEnums", + "variants": [ + { + "name": "dark", + "value": "dark" + }, + { + "name": "light", + "value": "light" + } + ] + } }, { "method": "contentString", @@ -3258,6 +3926,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -3271,6 +3953,7 @@ "wireName": "v", "type": "string", "required": true, + "literalValue": "3", "sourcePath": [ "bot" ] @@ -3290,7 +3973,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "child", @@ -3338,14 +4022,62 @@ "name": "type", "wireName": "type", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_ALL_CATEGORY_FEATURED", + "module": "WASmaxInBotEnums", + "variants": [ + { + "name": "all", + "value": "all" + }, + { + "name": "category", + "value": "category" + }, + { + "name": "featured", + "value": "featured" + } + ] + } }, { "method": "attrEnum", "name": "displayType", "wireName": "display_type", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_HIDDEN_HSCROLL_HSCROLLICEBREAKERS_HSCROLLLARGE_HSCROLLSMALL_LISTVIEW", + "module": "WASmaxInBotEnums", + "variants": [ + { + "name": "hidden", + "value": "hidden" + }, + { + "name": "hscroll", + "value": "hscroll" + }, + { + "name": "hscroll_icebreakers", + "value": "hscroll_icebreakers" + }, + { + "name": "hscroll_large", + "value": "hscroll_large" + }, + { + "name": "hscroll_small", + "value": "hscroll_small" + }, + { + "name": "listview", + "value": "listview" + } + ] + } }, { "method": "child", @@ -3397,11 +4129,47 @@ "tag": "BotListResponseError", "moduleName": "WASmaxInBotBotListResponseError", "kind": "error", + "errorArms": [ + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorForbidden", + "code": 403, + "text": "forbidden" + }, + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorNotAllowed", + "code": 405, + "text": "not-allowed" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -3414,7 +4182,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -3430,14 +4199,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -3449,6 +4220,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -3460,14 +4236,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "forbidden" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "403" } ], "assertions": [ @@ -3479,6 +4257,11 @@ "kind": "attr", "name": "text", "value": "forbidden" + }, + { + "kind": "attr", + "name": "code", + "value": "403" } ] }, @@ -3490,14 +4273,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -3509,6 +4294,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -3520,14 +4310,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-allowed" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "405" } ], "assertions": [ @@ -3539,6 +4331,11 @@ "kind": "attr", "name": "text", "value": "not-allowed" + }, + { + "kind": "attr", + "name": "code", + "value": "405" } ] } @@ -3676,6 +4473,38 @@ "tag": "digest", "children": [] }, + { + "method": "child", + "name": "registration", + "type": "string", + "required": true, + "tag": "registration", + "children": [ + { + "method": "contentUint", + "name": "content", + "type": "integer", + "required": true, + "byteLength": 4 + } + ] + }, + { + "method": "child", + "name": "type", + "type": "string", + "required": true, + "tag": "type", + "children": [ + { + "method": "contentUint", + "name": "content", + "type": "integer", + "required": true, + "byteLength": 1 + } + ] + }, { "method": "child", "name": "identity", @@ -3692,6 +4521,22 @@ } ] }, + { + "method": "child", + "name": "id", + "type": "string", + "required": true, + "tag": "id", + "children": [ + { + "method": "contentUint", + "name": "content", + "type": "integer", + "required": true, + "byteLength": 3 + } + ] + }, { "method": "child", "name": "value", @@ -3724,6 +4569,13 @@ } ] }, + { + "method": "contentUint", + "name": "content", + "type": "integer", + "required": true, + "byteLength": 3 + }, { "method": "child", "name": "hash", @@ -3984,7 +4836,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "", @@ -4014,10 +4867,10 @@ "tag": "user", "children": [ { - "method": "attrJidWithType", + "method": "attrJidEnum", "name": "jid", "wireName": "jid", - "type": "jid", + "type": "jid_typed", "required": true }, { @@ -4041,7 +4894,8 @@ "name": "isCloudApi", "wireName": "is_cloud_api", "type": "string", - "required": false + "required": false, + "literalValue": "true" }, { "method": "contentBytes", @@ -4064,6 +4918,8 @@ "name": "typeElementValue", "type": "bytes", "required": true, + "byteLength": 1, + "literalValue": "05", "sourcePath": [ "type" ] @@ -4338,6 +5194,7 @@ "wireName": "code", "type": "integer", "required": true, + "literalValue": "500", "sourcePath": [ "error" ] @@ -4402,6 +5259,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -4414,7 +5285,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "", @@ -4444,10 +5316,10 @@ "tag": "user", "children": [ { - "method": "attrJidWithType", + "method": "attrJidEnum", "name": "jid", "wireName": "jid", - "type": "jid", + "type": "jid_typed", "required": true }, { @@ -4471,7 +5343,8 @@ "name": "isCloudApi", "wireName": "is_cloud_api", "type": "string", - "required": false + "required": false, + "literalValue": "true" }, { "method": "contentBytes", @@ -4494,6 +5367,8 @@ "name": "typeElementValue", "type": "bytes", "required": true, + "byteLength": 1, + "literalValue": "05", "sourcePath": [ "type" ] @@ -4768,6 +5643,7 @@ "wireName": "code", "type": "integer", "required": true, + "literalValue": "500", "sourcePath": [ "error" ] @@ -4826,12 +5702,43 @@ { "tag": "FetchKeyBundlesResponseRequestError", "moduleName": "WASmaxInPreKeysFetchKeyBundlesResponseRequestError", - "kind": "error", + "kind": "client_error", + "errorArms": [ + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorNoValidJID", + "code": 406, + "text": "not-acceptable" + }, + { + "name": "IQErrorFallbackClient", + "codeMin": 400, + "codeMax": 499 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -4844,7 +5751,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -4860,14 +5768,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -4879,6 +5789,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -4890,14 +5805,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-acceptable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "406" } ], "assertions": [ @@ -4909,6 +5826,11 @@ "kind": "attr", "name": "text", "value": "not-acceptable" + }, + { + "kind": "attr", + "name": "code", + "value": "406" } ] }, @@ -4949,12 +5871,38 @@ { "tag": "FetchKeyBundlesResponseServerError", "moduleName": "WASmaxInPreKeysFetchKeyBundlesResponseServerError", - "kind": "error", + "kind": "server_error", + "errorArms": [ + { + "name": "IQErrorServiceUnavailable", + "code": 503, + "text": "service-unavailable" + }, + { + "name": "IQErrorFallbackServer", + "codeMin": 500, + "codeMax": 599 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -4967,7 +5915,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -4983,14 +5932,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "assertions": [ @@ -5002,6 +5953,11 @@ "kind": "attr", "name": "text", "value": "service-unavailable" + }, + { + "kind": "attr", + "name": "code", + "value": "503" } ] }, @@ -5118,7 +6074,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "", @@ -5148,10 +6105,10 @@ "tag": "user", "children": [ { - "method": "attrJidWithType", + "method": "attrJidEnum", "name": "jid", "wireName": "jid", - "type": "jid", + "type": "jid_typed", "required": true }, { @@ -5164,10 +6121,10 @@ "name": "FetchMissingPreKeysUserSuccess", "fields": [ { - "method": "attrJidWithType", + "method": "attrJidEnum", "name": "jid", "wireName": "jid", - "type": "jid", + "type": "jid_typed", "required": true }, { @@ -5198,7 +6155,8 @@ "name": "isCloudApi", "wireName": "is_cloud_api", "type": "string", - "required": false + "required": false, + "literalValue": "true" }, { "method": "contentBytes", @@ -5221,6 +6179,8 @@ "name": "typeElementValue", "type": "bytes", "required": true, + "byteLength": 1, + "literalValue": "05", "sourcePath": [ "type" ] @@ -5446,6 +6406,7 @@ "wireName": "code", "type": "integer", "required": true, + "literalValue": "500", "sourcePath": [ "error" ] @@ -5510,6 +6471,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -5522,7 +6497,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "", @@ -5552,10 +6528,10 @@ "tag": "user", "children": [ { - "method": "attrJidWithType", + "method": "attrJidEnum", "name": "jid", "wireName": "jid", - "type": "jid", + "type": "jid_typed", "required": true }, { @@ -5568,10 +6544,10 @@ "name": "FetchMissingPreKeysUserSuccess", "fields": [ { - "method": "attrJidWithType", + "method": "attrJidEnum", "name": "jid", "wireName": "jid", - "type": "jid", + "type": "jid_typed", "required": true }, { @@ -5602,7 +6578,8 @@ "name": "isCloudApi", "wireName": "is_cloud_api", "type": "string", - "required": false + "required": false, + "literalValue": "true" }, { "method": "contentBytes", @@ -5625,6 +6602,8 @@ "name": "typeElementValue", "type": "bytes", "required": true, + "byteLength": 1, + "literalValue": "05", "sourcePath": [ "type" ] @@ -5850,6 +6829,7 @@ "wireName": "code", "type": "integer", "required": true, + "literalValue": "500", "sourcePath": [ "error" ] @@ -5908,12 +6888,43 @@ { "tag": "FetchMissingPreKeysResponseRequestError", "moduleName": "WASmaxInPreKeysFetchMissingPreKeysResponseRequestError", - "kind": "error", + "kind": "client_error", + "errorArms": [ + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorNoValidJID", + "code": 406, + "text": "not-acceptable" + }, + { + "name": "IQErrorFallbackClient", + "codeMin": 400, + "codeMax": 499 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -5926,7 +6937,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -5942,14 +6954,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -5961,6 +6975,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -5972,14 +6991,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-acceptable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "406" } ], "assertions": [ @@ -5991,6 +7012,11 @@ "kind": "attr", "name": "text", "value": "not-acceptable" + }, + { + "kind": "attr", + "name": "code", + "value": "406" } ] }, @@ -6031,12 +7057,38 @@ { "tag": "FetchMissingPreKeysResponseServerError", "moduleName": "WASmaxInPreKeysFetchMissingPreKeysResponseServerError", - "kind": "error", + "kind": "server_error", + "errorArms": [ + { + "name": "IQErrorServiceUnavailable", + "code": 503, + "text": "service-unavailable" + }, + { + "name": "IQErrorFallbackServer", + "codeMin": 500, + "codeMax": 599 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -6049,7 +7101,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -6065,14 +7118,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "assertions": [ @@ -6084,6 +7139,11 @@ "kind": "attr", "name": "text", "value": "service-unavailable" + }, + { + "kind": "attr", + "name": "code", + "value": "503" } ] }, @@ -6299,7 +7359,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "", @@ -6313,6 +7374,7 @@ "wireName": "count_low", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "list" ] @@ -6332,6 +7394,7 @@ "wireName": "count_low", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "pq_list" ] @@ -6350,6 +7413,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -6362,7 +7439,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "", @@ -6376,6 +7454,7 @@ "wireName": "count_low", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "list" ] @@ -6395,6 +7474,7 @@ "wireName": "count_low", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "pq_list" ] @@ -6407,12 +7487,38 @@ { "tag": "AddResponseRequestError", "moduleName": "WASmaxInPreKeysAddResponseRequestError", - "kind": "error", + "kind": "client_error", + "errorArms": [ + { + "name": "IQErrorNotAcceptable", + "code": 406, + "text": "not-acceptable" + }, + { + "name": "IQErrorFallbackClient", + "codeMin": 400, + "codeMax": 499 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -6425,7 +7531,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -6441,14 +7548,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-acceptable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "406" }, { "method": "child", @@ -6484,6 +7593,11 @@ "kind": "attr", "name": "text", "value": "not-acceptable" + }, + { + "kind": "attr", + "name": "code", + "value": "406" } ] }, @@ -6524,12 +7638,38 @@ { "tag": "AddResponseServerError", "moduleName": "WASmaxInPreKeysAddResponseServerError", - "kind": "error", + "kind": "server_error", + "errorArms": [ + { + "name": "IQErrorServiceUnavailable", + "code": 503, + "text": "service-unavailable" + }, + { + "name": "IQErrorFallbackServer", + "codeMin": 500, + "codeMax": 599 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -6542,7 +7682,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -6558,14 +7699,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "assertions": [ @@ -6577,6 +7720,11 @@ "kind": "attr", "name": "text", "value": "service-unavailable" + }, + { + "kind": "attr", + "name": "code", + "value": "503" } ] }, @@ -6670,7 +7818,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ], "variants": [ @@ -6683,6 +7832,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -6695,19 +7858,46 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ] }, { "tag": "DeleteResponseRequestError", "moduleName": "WASmaxInPreKeysDeleteResponseRequestError", - "kind": "error", + "kind": "client_error", + "errorArms": [ + { + "name": "IQErrorNotAcceptable", + "code": 406, + "text": "not-acceptable" + }, + { + "name": "IQErrorFallbackClient", + "codeMin": 400, + "codeMax": 499 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -6720,7 +7910,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -6736,14 +7927,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-acceptable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "406" }, { "method": "child", @@ -6779,6 +7972,11 @@ "kind": "attr", "name": "text", "value": "not-acceptable" + }, + { + "kind": "attr", + "name": "code", + "value": "406" } ] }, @@ -6819,12 +8017,38 @@ { "tag": "DeleteResponseServerError", "moduleName": "WASmaxInPreKeysDeleteResponseServerError", - "kind": "error", + "kind": "server_error", + "errorArms": [ + { + "name": "IQErrorServiceUnavailable", + "code": 503, + "text": "service-unavailable" + }, + { + "name": "IQErrorFallbackServer", + "codeMin": 500, + "codeMax": 599 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -6837,7 +8061,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -6853,14 +8078,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "assertions": [ @@ -6872,6 +8099,11 @@ "kind": "attr", "name": "text", "value": "service-unavailable" + }, + { + "kind": "attr", + "name": "code", + "value": "503" } ] }, @@ -6937,7 +8169,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "", @@ -6951,6 +8184,7 @@ "wireName": "count_low", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "list" ] @@ -6970,6 +8204,7 @@ "wireName": "count_low", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "pq_list" ] @@ -6988,6 +8223,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -7000,7 +8249,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "", @@ -7014,6 +8264,7 @@ "wireName": "count_low", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "list" ] @@ -7033,6 +8284,7 @@ "wireName": "count_low", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "pq_list" ] @@ -7045,12 +8297,54 @@ { "tag": "SetResponsePreKeySuccessVnameFailure", "moduleName": "WASmaxInPreKeysSetResponsePreKeySuccessVnameFailure", - "kind": "success", + "kind": "error", + "errorArms": [ + { + "name": "SetVnameFailureNotAcceptable", + "text": "not-acceptable", + "codeMin": 400, + "codeMax": 599 + }, + { + "name": "SetVnameFailureBadRequest", + "text": "bad-request", + "codeMin": 400, + "codeMax": 599 + }, + { + "name": "SetVnameFailureInternalServerError", + "text": "internal-server-error", + "codeMin": 400, + "codeMax": 599 + }, + { + "name": "SetVnameFailureFallback", + "codeMin": 400, + "codeMax": 599 + } + ], + "errorEnvelope": { + "code": 207 + }, "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -7074,6 +8368,7 @@ "wireName": "code", "type": "integer", "required": true, + "literalValue": "207", "sourcePath": [ "error" ] @@ -7096,7 +8391,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -7112,7 +8408,8 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-acceptable" }, { "method": "attrString", @@ -7165,7 +8462,8 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" } ], "assertions": [ @@ -7188,7 +8486,8 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" } ], "assertions": [ @@ -7232,12 +8531,38 @@ { "tag": "SetResponseRequestError", "moduleName": "WASmaxInPreKeysSetResponseRequestError", - "kind": "error", + "kind": "client_error", + "errorArms": [ + { + "name": "IQErrorNotAcceptable", + "code": 406, + "text": "not-acceptable" + }, + { + "name": "IQErrorFallbackClient", + "codeMin": 400, + "codeMax": 499 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -7250,7 +8575,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -7266,14 +8592,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-acceptable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "406" }, { "method": "child", @@ -7309,6 +8637,11 @@ "kind": "attr", "name": "text", "value": "not-acceptable" + }, + { + "kind": "attr", + "name": "code", + "value": "406" } ] }, @@ -7349,12 +8682,38 @@ { "tag": "SetResponseServerError", "moduleName": "WASmaxInPreKeysSetResponseServerError", - "kind": "error", + "kind": "server_error", + "errorArms": [ + { + "name": "IQErrorServiceUnavailable", + "code": 503, + "text": "service-unavailable" + }, + { + "name": "IQErrorFallbackServer", + "codeMin": 500, + "codeMax": 599 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -7367,7 +8726,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -7383,14 +8743,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "assertions": [ @@ -7402,6 +8764,11 @@ "kind": "attr", "name": "text", "value": "service-unavailable" + }, + { + "kind": "attr", + "name": "code", + "value": "503" } ] }, @@ -7656,8 +9023,12 @@ { "method": "attrEnum", "name": "type", - "type": "string", - "required": true + "type": "enum", + "required": true, + "enumKeys": [ + "error", + "result" + ] }, { "method": "child", @@ -7757,7 +9128,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "child", @@ -7767,10 +9139,24 @@ "tag": "token_type", "children": [ { - "method": "attrEnum", + "method": "contentEnum", "name": "elementValue", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_STRONG_WEAK", + "module": "WASmaxInBizCtwaAdAccountEnums", + "variants": [ + { + "name": "Strong", + "value": "Strong" + }, + { + "name": "Weak", + "value": "Weak" + } + ] + } } ], "repeats": false @@ -7786,6 +9172,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -7833,7 +9233,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "child", @@ -7843,10 +9244,24 @@ "tag": "token_type", "children": [ { - "method": "attrEnum", + "method": "contentEnum", "name": "elementValue", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_STRONG_WEAK", + "module": "WASmaxInBizCtwaAdAccountEnums", + "variants": [ + { + "name": "Strong", + "value": "Strong" + }, + { + "name": "Weak", + "value": "Weak" + } + ] + } } ], "repeats": false @@ -7856,12 +9271,32 @@ { "tag": "GetAccessTokenAndSessionCookiesResponseTooManyAttempts", "moduleName": "WASmaxInBizCtwaAdAccountGetAccessTokenAndSessionCookiesResponseTooManyAttempts", - "kind": "error", + "kind": "client_error", + "errorArms": [ + { + "code": 431, + "text": "TOO_MANY_ATTEMPTS" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -7875,6 +9310,7 @@ "wireName": "code", "type": "string", "required": true, + "literalValue": "431", "sourcePath": [ "error" ] @@ -7885,6 +9321,7 @@ "wireName": "text", "type": "string", "required": true, + "literalValue": "TOO_MANY_ATTEMPTS", "sourcePath": [ "error" ] @@ -7901,19 +9338,40 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ] }, { "tag": "GetAccessTokenAndSessionCookiesResponseIncorrectNonce", "moduleName": "WASmaxInBizCtwaAdAccountGetAccessTokenAndSessionCookiesResponseIncorrectNonce", - "kind": "error", + "kind": "client_error", + "errorArms": [ + { + "code": 432, + "text": "INCORRECT_NONCE" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -7927,6 +9385,7 @@ "wireName": "code", "type": "string", "required": true, + "literalValue": "432", "sourcePath": [ "error" ] @@ -7937,6 +9396,7 @@ "wireName": "text", "type": "string", "required": true, + "literalValue": "INCORRECT_NONCE", "sourcePath": [ "error" ] @@ -7953,7 +9413,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ] }, @@ -7961,11 +9422,47 @@ "tag": "GetAccessTokenAndSessionCookiesResponseError", "moduleName": "WASmaxInBizCtwaAdAccountGetAccessTokenAndSessionCookiesResponseError", "kind": "error", + "errorArms": [ + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorForbidden", + "code": 403, + "text": "forbidden" + }, + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorServiceUnavailable", + "code": 503, + "text": "service-unavailable" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -7985,7 +9482,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -8001,14 +9499,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -8020,6 +9520,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -8031,14 +9536,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "forbidden" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "403" } ], "assertions": [ @@ -8050,6 +9557,11 @@ "kind": "attr", "name": "text", "value": "forbidden" + }, + { + "kind": "attr", + "name": "code", + "value": "403" } ] }, @@ -8061,14 +9573,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -8080,6 +9594,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -8091,14 +9610,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "assertions": [ @@ -8110,6 +9631,11 @@ "kind": "attr", "name": "text", "value": "service-unavailable" + }, + { + "kind": "attr", + "name": "code", + "value": "503" } ] } @@ -8179,7 +9705,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "child", @@ -8214,6 +9741,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -8243,7 +9784,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "child", @@ -8273,11 +9815,42 @@ "tag": "GetAccountNonceResponseError", "moduleName": "WASmaxInBizLinkingGetAccountNonceResponseError", "kind": "error", + "errorArms": [ + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorNoticeRequired", + "code": 475, + "text": "notice-required" + }, + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -8297,7 +9870,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -8313,14 +9887,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -8332,6 +9908,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -8343,14 +9924,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "notice-required" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "475" }, { "method": "attrInt", @@ -8371,6 +9954,11 @@ "kind": "attr", "name": "text", "value": "notice-required" + }, + { + "kind": "attr", + "name": "code", + "value": "475" } ] }, @@ -8382,14 +9970,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -8401,6 +9991,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] } @@ -8453,7 +10048,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "child", @@ -8468,6 +10064,20 @@ "wireName": "state", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_OFF_ON", + "module": "WASmaxInBizLinkingEnums", + "variants": [ + { + "name": "off", + "value": "off" + }, + { + "name": "on", + "value": "on" + } + ] + }, "sourcePath": [ "whatsapp_as_page_button" ] @@ -8494,6 +10104,20 @@ "wireName": "has_created_ad", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInBizLinkingEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + }, "sourcePath": [ "ad_status" ] @@ -8504,6 +10128,20 @@ "wireName": "has_active_ctwa_ad", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInBizLinkingEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + }, "sourcePath": [ "ad_status" ] @@ -8520,7 +10158,21 @@ "name": "state", "wireName": "state", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_DISABLE_IMPORT", + "module": "WASmaxInBizLinkingEnums", + "variants": [ + { + "name": "disable", + "value": "disable" + }, + { + "name": "import", + "value": "import" + } + ] + } } ], "repeats": false @@ -8570,10 +10222,24 @@ "required": false, "children": [ { - "method": "attrEnum", + "method": "contentEnum", "name": "showOnProfileElementValue", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInBizLinkingEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + }, "sourcePath": [ "show_on_profile" ] @@ -8622,7 +10288,21 @@ "name": "state", "wireName": "state", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_DISABLE_IMPORT", + "module": "WASmaxInBizLinkingEnums", + "variants": [ + { + "name": "disable", + "value": "disable" + }, + { + "name": "import", + "value": "import" + } + ] + } }, { "method": "attrString", @@ -8719,10 +10399,24 @@ "required": false, "children": [ { - "method": "attrEnum", + "method": "contentEnum", "name": "showOnProfileElementValue", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInBizLinkingEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + }, "sourcePath": [ "show_on_profile" ] @@ -8756,6 +10450,20 @@ "wireName": "has_created_ad", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInBizLinkingEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + }, "sourcePath": [ "ad_status" ] @@ -8766,6 +10474,20 @@ "wireName": "has_active_ctwa_ad", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInBizLinkingEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + }, "sourcePath": [ "ad_status" ] @@ -8787,6 +10509,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -8806,7 +10542,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "child", @@ -8821,6 +10558,20 @@ "wireName": "state", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_OFF_ON", + "module": "WASmaxInBizLinkingEnums", + "variants": [ + { + "name": "off", + "value": "off" + }, + { + "name": "on", + "value": "on" + } + ] + }, "sourcePath": [ "whatsapp_as_page_button" ] @@ -8847,6 +10598,20 @@ "wireName": "has_created_ad", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInBizLinkingEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + }, "sourcePath": [ "ad_status" ] @@ -8857,6 +10622,20 @@ "wireName": "has_active_ctwa_ad", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInBizLinkingEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + }, "sourcePath": [ "ad_status" ] @@ -8873,7 +10652,21 @@ "name": "state", "wireName": "state", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_DISABLE_IMPORT", + "module": "WASmaxInBizLinkingEnums", + "variants": [ + { + "name": "disable", + "value": "disable" + }, + { + "name": "import", + "value": "import" + } + ] + } } ], "repeats": false @@ -8923,10 +10716,24 @@ "required": false, "children": [ { - "method": "attrEnum", + "method": "contentEnum", "name": "showOnProfileElementValue", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInBizLinkingEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + }, "sourcePath": [ "show_on_profile" ] @@ -8975,7 +10782,21 @@ "name": "state", "wireName": "state", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_DISABLE_IMPORT", + "module": "WASmaxInBizLinkingEnums", + "variants": [ + { + "name": "disable", + "value": "disable" + }, + { + "name": "import", + "value": "import" + } + ] + } }, { "method": "attrString", @@ -9072,10 +10893,24 @@ "required": false, "children": [ { - "method": "attrEnum", + "method": "contentEnum", "name": "showOnProfileElementValue", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInBizLinkingEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + }, "sourcePath": [ "show_on_profile" ] @@ -9109,6 +10944,20 @@ "wireName": "has_created_ad", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInBizLinkingEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + }, "sourcePath": [ "ad_status" ] @@ -9119,6 +10968,20 @@ "wireName": "has_active_ctwa_ad", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInBizLinkingEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + }, "sourcePath": [ "ad_status" ] @@ -9134,12 +10997,32 @@ { "tag": "GetLinkedAccountsResponseForbidden", "moduleName": "WASmaxInBizLinkingGetLinkedAccountsResponseForbidden", - "kind": "error", + "kind": "client_error", + "errorArms": [ + { + "code": 403, + "text": "forbidden" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -9159,14 +11042,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "forbidden" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "403" } ], "repeats": false @@ -9183,19 +11068,40 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ] }, { "tag": "GetLinkedAccountsResponseError", "moduleName": "WASmaxInBizLinkingGetLinkedAccountsResponseError", - "kind": "error", + "kind": "server_error", + "errorArms": [ + { + "code": 500, + "text": "internal-server-error" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -9215,14 +11121,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "repeats": false @@ -9239,7 +11147,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ] } @@ -9272,6 +11181,7 @@ "wireName": "status", "type": "string", "required": true, + "literalValue": "Success", "sourcePath": [ "result" ] @@ -9288,7 +11198,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ], "variants": [ @@ -9301,6 +11212,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -9314,6 +11239,7 @@ "wireName": "status", "type": "string", "required": true, + "literalValue": "Success", "sourcePath": [ "result" ] @@ -9330,19 +11256,34 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ] }, { "tag": "RequestSilentNonceResponseRecoveryRequired", "moduleName": "WASmaxInBizAccessTokenRequestSilentNonceResponseRecoveryRequired", - "kind": "error", + "kind": "alternative", "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -9356,6 +11297,7 @@ "wireName": "status", "type": "string", "required": true, + "literalValue": "RecoveryRequired", "sourcePath": [ "result" ] @@ -9382,7 +11324,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ] }, @@ -9390,11 +11333,47 @@ "tag": "RequestSilentNonceResponseError", "moduleName": "WASmaxInBizAccessTokenRequestSilentNonceResponseError", "kind": "error", + "errorArms": [ + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorForbidden", + "code": 403, + "text": "forbidden" + }, + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorServiceUnavailable", + "code": 503, + "text": "service-unavailable" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -9414,7 +11393,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -9430,14 +11410,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -9449,6 +11431,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -9460,14 +11447,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "forbidden" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "403" } ], "assertions": [ @@ -9479,6 +11468,11 @@ "kind": "attr", "name": "text", "value": "forbidden" + }, + { + "kind": "attr", + "name": "code", + "value": "403" } ] }, @@ -9490,14 +11484,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -9509,6 +11505,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -9520,14 +11521,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "assertions": [ @@ -9539,6 +11542,11 @@ "kind": "attr", "name": "text", "value": "service-unavailable" + }, + { + "kind": "attr", + "name": "code", + "value": "503" } ] } @@ -9580,10 +11588,24 @@ "tag": "Result", "children": [ { - "method": "attrEnum", + "method": "contentEnum", "name": "statusElementValue", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_FAIL_SUCCESS", + "module": "WASmaxInBizCtwaAdAccountEnums", + "variants": [ + { + "name": "Fail", + "value": "Fail" + }, + { + "name": "Success", + "value": "Success" + } + ] + }, "sourcePath": [ "status" ] @@ -9603,7 +11625,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ], "variants": [ @@ -9616,6 +11639,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -9631,10 +11668,24 @@ "tag": "Result", "children": [ { - "method": "attrEnum", + "method": "contentEnum", "name": "statusElementValue", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_FAIL_SUCCESS", + "module": "WASmaxInBizCtwaAdAccountEnums", + "variants": [ + { + "name": "Fail", + "value": "Fail" + }, + { + "name": "Success", + "value": "Success" + } + ] + }, "sourcePath": [ "status" ] @@ -9654,7 +11705,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ] }, @@ -9662,11 +11714,47 @@ "tag": "SendAccountRecoveryNonceResponseError", "moduleName": "WASmaxInBizCtwaAdAccountSendAccountRecoveryNonceResponseError", "kind": "error", + "errorArms": [ + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorForbidden", + "code": 403, + "text": "forbidden" + }, + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorServiceUnavailable", + "code": 503, + "text": "service-unavailable" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -9686,7 +11774,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -9702,14 +11791,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -9721,6 +11812,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -9732,14 +11828,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "forbidden" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "403" } ], "assertions": [ @@ -9751,6 +11849,11 @@ "kind": "attr", "name": "text", "value": "forbidden" + }, + { + "kind": "attr", + "name": "code", + "value": "403" } ] }, @@ -9762,14 +11865,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -9781,6 +11886,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -9792,14 +11902,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "assertions": [ @@ -9811,6 +11923,11 @@ "kind": "attr", "name": "text", "value": "service-unavailable" + }, + { + "kind": "attr", + "name": "code", + "value": "503" } ] } @@ -10224,7 +12341,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "child", @@ -10245,7 +12363,21 @@ "name": "type", "wireName": "type", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_IMAGE_VIDEO", + "module": "WASmaxInBizCtwaNativeAdEnums", + "variants": [ + { + "name": "image", + "value": "image" + }, + { + "name": "video", + "value": "video" + } + ] + } } ], "repeats": false @@ -10269,7 +12401,21 @@ "name": "type", "wireName": "type", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_IMAGE_VIDEO", + "module": "WASmaxInBizCtwaNativeAdEnums", + "variants": [ + { + "name": "image", + "value": "image" + }, + { + "name": "video", + "value": "video" + } + ] + } } ], "repeats": true @@ -10285,6 +12431,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -10304,7 +12464,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "child", @@ -10325,7 +12486,21 @@ "name": "type", "wireName": "type", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_IMAGE_VIDEO", + "module": "WASmaxInBizCtwaNativeAdEnums", + "variants": [ + { + "name": "image", + "value": "image" + }, + { + "name": "video", + "value": "video" + } + ] + } } ], "repeats": false @@ -10349,7 +12524,21 @@ "name": "type", "wireName": "type", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_IMAGE_VIDEO", + "module": "WASmaxInBizCtwaNativeAdEnums", + "variants": [ + { + "name": "image", + "value": "image" + }, + { + "name": "video", + "value": "video" + } + ] + } } ], "repeats": true @@ -10360,11 +12549,40 @@ "tag": "UploadAdMediaResponseError", "moduleName": "WASmaxInBizCtwaNativeAdUploadAdMediaResponseError", "kind": "error", + "errorArms": [ + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorForbidden", + "code": 403, + "text": "forbidden" + }, + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorServiceUnavailable", + "code": 503, + "text": "service-unavailable" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, { "kind": "attr", "name": "type", @@ -10373,10 +12591,10 @@ ], "fields": [ { - "method": "attrJidWithType", + "method": "attrJidEnum", "name": "from", "wireName": "from", - "type": "jid", + "type": "jid_typed", "required": false }, { @@ -10384,7 +12602,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -10400,14 +12619,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -10419,6 +12640,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -10430,14 +12656,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "forbidden" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "403" } ], "assertions": [ @@ -10449,6 +12677,11 @@ "kind": "attr", "name": "text", "value": "forbidden" + }, + { + "kind": "attr", + "name": "code", + "value": "403" } ] }, @@ -10460,14 +12693,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -10479,6 +12714,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -10490,14 +12730,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "assertions": [ @@ -10509,6 +12751,11 @@ "kind": "attr", "name": "text", "value": "service-unavailable" + }, + { + "kind": "attr", + "name": "code", + "value": "503" } ] } @@ -10624,7 +12871,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ], "variants": [ @@ -10637,6 +12885,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -10659,7 +12921,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ] }, @@ -10667,11 +12930,37 @@ "tag": "GetCountryCodeResponseError", "moduleName": "WASmaxInMdGetCountryCodeResponseError", "kind": "error", + "errorArms": [ + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -10684,7 +12973,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -10700,14 +12990,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -10719,6 +13011,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -10730,14 +13027,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -10749,6 +13048,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] } @@ -10812,7 +13116,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ], "variants": [ @@ -10825,6 +13130,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -10855,19 +13174,40 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ] }, { "tag": "GetPasskeyRequestOptionsResponseError", "moduleName": "WASmaxInMdGetPasskeyRequestOptionsResponseError", - "kind": "error", + "kind": "server_error", + "errorArms": [ + { + "code": 500, + "text": "internal-server-error" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -10887,14 +13227,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "repeats": false @@ -10904,7 +13246,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ] } @@ -10952,7 +13295,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ], "variants": [ @@ -10965,6 +13309,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -10986,7 +13344,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ] } @@ -11056,7 +13415,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ], "variants": [ @@ -11069,6 +13429,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -11081,7 +13455,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ] }, @@ -11089,11 +13464,37 @@ "tag": "CompanionFinishResponseError", "moduleName": "WASmaxInMdCompanionFinishResponseError", "kind": "error", + "errorArms": [ + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -11106,7 +13507,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -11122,14 +13524,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -11141,6 +13545,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -11152,14 +13561,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -11171,6 +13582,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] } @@ -11272,6 +13688,7 @@ "wireName": "stage", "type": "string", "required": true, + "literalValue": "companion_hello", "sourcePath": [ "link_code_companion_reg" ] @@ -11291,7 +13708,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ], "variants": [ @@ -11304,6 +13722,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -11317,6 +13749,7 @@ "wireName": "stage", "type": "string", "required": true, + "literalValue": "companion_hello", "sourcePath": [ "link_code_companion_reg" ] @@ -11336,7 +13769,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ] }, @@ -11344,11 +13778,52 @@ "tag": "CompanionHelloResponseError", "moduleName": "WASmaxInMdCompanionHelloResponseError", "kind": "error", + "errorArms": [ + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorFeatureNotAvailable", + "code": 452, + "text": "feature-not-available" + }, + { + "name": "IQErrorRateOverlimit", + "code": 429, + "text": "rate-overlimit" + }, + { + "name": "IQErrorForbidden", + "code": 403, + "text": "forbidden" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -11361,7 +13836,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -11377,14 +13853,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -11396,6 +13874,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -11407,14 +13890,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -11426,6 +13911,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -11437,14 +13927,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "feature-not-available" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "452" } ], "assertions": [ @@ -11456,6 +13948,11 @@ "kind": "attr", "name": "text", "value": "feature-not-available" + }, + { + "kind": "attr", + "name": "code", + "value": "452" } ] }, @@ -11467,14 +13964,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "rate-overlimit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "429" } ], "assertions": [ @@ -11486,6 +13985,11 @@ "kind": "attr", "name": "text", "value": "rate-overlimit" + }, + { + "kind": "attr", + "name": "code", + "value": "429" } ] }, @@ -11497,14 +14001,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "forbidden" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "403" } ], "assertions": [ @@ -11516,6 +14022,11 @@ "kind": "attr", "name": "text", "value": "forbidden" + }, + { + "kind": "attr", + "name": "code", + "value": "403" } ] } @@ -11561,7 +14072,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ], "variants": [ @@ -11574,6 +14086,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -11586,7 +14112,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ] } @@ -11625,7 +14152,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ], "variants": [ @@ -11638,6 +14166,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -11650,7 +14192,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ] } @@ -11715,7 +14258,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ], "variants": [ @@ -11728,6 +14272,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -11740,7 +14298,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ] } @@ -11911,7 +14470,8 @@ "name": "isSender", "wireName": "is_sender", "type": "string", - "required": false + "required": false, + "literalValue": "true" }, { "method": "", @@ -12046,6 +14606,7 @@ "wireName": "questiontype", "type": "string", "required": true, + "literalValue": "question", "sourcePath": [ "meta" ] @@ -12062,6 +14623,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -12101,7 +14663,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" }, { "method": "", @@ -12115,6 +14678,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -12144,6 +14708,92 @@ "wireName": "mediatype", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_1PSTICKER_AUDIO_AVATARSTICKER_CATALOGLINK_COLLECTION_DOCUMENT_GENAISTICKER_GIF_IMAGE_MOTIONPHOTO_MOTIONVIDEO_PRODUCTLINK_PTT_PTV_STICKER_STICKERPACK_URL_USERCREATEDSTICKER_VCARD_VIDEO", + "module": "WASmaxInNewslettersEnums", + "variants": [ + { + "name": "1p_sticker", + "value": "1p_sticker" + }, + { + "name": "audio", + "value": "audio" + }, + { + "name": "avatar_sticker", + "value": "avatar_sticker" + }, + { + "name": "cataloglink", + "value": "cataloglink" + }, + { + "name": "collection", + "value": "collection" + }, + { + "name": "document", + "value": "document" + }, + { + "name": "genai_sticker", + "value": "genai_sticker" + }, + { + "name": "gif", + "value": "gif" + }, + { + "name": "image", + "value": "image" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "motion_video", + "value": "motion_video" + }, + { + "name": "productlink", + "value": "productlink" + }, + { + "name": "ptt", + "value": "ptt" + }, + { + "name": "ptv", + "value": "ptv" + }, + { + "name": "sticker", + "value": "sticker" + }, + { + "name": "sticker_pack", + "value": "sticker_pack" + }, + { + "name": "url", + "value": "url" + }, + { + "name": "user_created_sticker", + "value": "user_created_sticker" + }, + { + "name": "vcard", + "value": "vcard" + }, + { + "name": "video", + "value": "video" + } + ] + }, "sourcePath": [ "plaintext" ] @@ -12171,7 +14821,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" }, { "method": "", @@ -12185,6 +14836,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -12204,6 +14856,40 @@ "wireName": "message_association_type", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_HDIMAGEDUALUPLOAD_HDVIDEODUALUPLOAD_HEVCVIDEODUALUPLOAD_MEDIAPOLL_MOTIONPHOTO_POLLADDOPTION_STICKERANNOTATION", + "module": "WASmaxInNewslettersEnums", + "variants": [ + { + "name": "hd_image_dual_upload", + "value": "hd_image_dual_upload" + }, + { + "name": "hd_video_dual_upload", + "value": "hd_video_dual_upload" + }, + { + "name": "hevc_video_dual_upload", + "value": "hevc_video_dual_upload" + }, + { + "name": "media_poll", + "value": "media_poll" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "poll_add_option", + "value": "poll_add_option" + }, + { + "name": "sticker_annotation", + "value": "sticker_annotation" + } + ] + }, "sourcePath": [ "meta" ] @@ -12261,7 +14947,8 @@ "name": "edit", "wireName": "edit", "type": "string", - "required": true + "required": true, + "literalValue": "3" }, { "method": "", @@ -12275,6 +14962,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -12297,6 +14985,7 @@ "wireName": "questiontype", "type": "string", "required": true, + "literalValue": "reply", "sourcePath": [ "meta" ] @@ -12313,6 +15002,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -12352,7 +15042,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" }, { "method": "", @@ -12366,6 +15057,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -12395,6 +15087,92 @@ "wireName": "mediatype", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_1PSTICKER_AUDIO_AVATARSTICKER_CATALOGLINK_COLLECTION_DOCUMENT_GENAISTICKER_GIF_IMAGE_MOTIONPHOTO_MOTIONVIDEO_PRODUCTLINK_PTT_PTV_STICKER_STICKERPACK_URL_USERCREATEDSTICKER_VCARD_VIDEO", + "module": "WASmaxInNewslettersEnums", + "variants": [ + { + "name": "1p_sticker", + "value": "1p_sticker" + }, + { + "name": "audio", + "value": "audio" + }, + { + "name": "avatar_sticker", + "value": "avatar_sticker" + }, + { + "name": "cataloglink", + "value": "cataloglink" + }, + { + "name": "collection", + "value": "collection" + }, + { + "name": "document", + "value": "document" + }, + { + "name": "genai_sticker", + "value": "genai_sticker" + }, + { + "name": "gif", + "value": "gif" + }, + { + "name": "image", + "value": "image" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "motion_video", + "value": "motion_video" + }, + { + "name": "productlink", + "value": "productlink" + }, + { + "name": "ptt", + "value": "ptt" + }, + { + "name": "ptv", + "value": "ptv" + }, + { + "name": "sticker", + "value": "sticker" + }, + { + "name": "sticker_pack", + "value": "sticker_pack" + }, + { + "name": "url", + "value": "url" + }, + { + "name": "user_created_sticker", + "value": "user_created_sticker" + }, + { + "name": "vcard", + "value": "vcard" + }, + { + "name": "video", + "value": "video" + } + ] + }, "sourcePath": [ "plaintext" ] @@ -12422,7 +15200,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" }, { "method": "", @@ -12436,6 +15215,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -12455,6 +15235,40 @@ "wireName": "message_association_type", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_HDIMAGEDUALUPLOAD_HDVIDEODUALUPLOAD_HEVCVIDEODUALUPLOAD_MEDIAPOLL_MOTIONPHOTO_POLLADDOPTION_STICKERANNOTATION", + "module": "WASmaxInNewslettersEnums", + "variants": [ + { + "name": "hd_image_dual_upload", + "value": "hd_image_dual_upload" + }, + { + "name": "hd_video_dual_upload", + "value": "hd_video_dual_upload" + }, + { + "name": "hevc_video_dual_upload", + "value": "hevc_video_dual_upload" + }, + { + "name": "media_poll", + "value": "media_poll" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "poll_add_option", + "value": "poll_add_option" + }, + { + "name": "sticker_annotation", + "value": "sticker_annotation" + } + ] + }, "sourcePath": [ "meta" ] @@ -12530,7 +15344,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" }, { "method": "", @@ -12544,6 +15359,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -12573,6 +15389,92 @@ "wireName": "mediatype", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_1PSTICKER_AUDIO_AVATARSTICKER_CATALOGLINK_COLLECTION_DOCUMENT_GENAISTICKER_GIF_IMAGE_MOTIONPHOTO_MOTIONVIDEO_PRODUCTLINK_PTT_PTV_STICKER_STICKERPACK_URL_USERCREATEDSTICKER_VCARD_VIDEO", + "module": "WASmaxInNewslettersEnums", + "variants": [ + { + "name": "1p_sticker", + "value": "1p_sticker" + }, + { + "name": "audio", + "value": "audio" + }, + { + "name": "avatar_sticker", + "value": "avatar_sticker" + }, + { + "name": "cataloglink", + "value": "cataloglink" + }, + { + "name": "collection", + "value": "collection" + }, + { + "name": "document", + "value": "document" + }, + { + "name": "genai_sticker", + "value": "genai_sticker" + }, + { + "name": "gif", + "value": "gif" + }, + { + "name": "image", + "value": "image" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "motion_video", + "value": "motion_video" + }, + { + "name": "productlink", + "value": "productlink" + }, + { + "name": "ptt", + "value": "ptt" + }, + { + "name": "ptv", + "value": "ptv" + }, + { + "name": "sticker", + "value": "sticker" + }, + { + "name": "sticker_pack", + "value": "sticker_pack" + }, + { + "name": "url", + "value": "url" + }, + { + "name": "user_created_sticker", + "value": "user_created_sticker" + }, + { + "name": "vcard", + "value": "vcard" + }, + { + "name": "video", + "value": "video" + } + ] + }, "sourcePath": [ "plaintext" ] @@ -12600,7 +15502,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" }, { "method": "", @@ -12614,6 +15517,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -12633,6 +15537,40 @@ "wireName": "message_association_type", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_HDIMAGEDUALUPLOAD_HDVIDEODUALUPLOAD_HEVCVIDEODUALUPLOAD_MEDIAPOLL_MOTIONPHOTO_POLLADDOPTION_STICKERANNOTATION", + "module": "WASmaxInNewslettersEnums", + "variants": [ + { + "name": "hd_image_dual_upload", + "value": "hd_image_dual_upload" + }, + { + "name": "hd_video_dual_upload", + "value": "hd_video_dual_upload" + }, + { + "name": "hevc_video_dual_upload", + "value": "hevc_video_dual_upload" + }, + { + "name": "media_poll", + "value": "media_poll" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "poll_add_option", + "value": "poll_add_option" + }, + { + "name": "sticker_annotation", + "value": "sticker_annotation" + } + ] + }, "sourcePath": [ "meta" ] @@ -12696,6 +15634,7 @@ "wireName": "questiontype", "type": "string", "required": true, + "literalValue": "reply", "sourcePath": [ "meta" ] @@ -12712,6 +15651,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -12751,7 +15691,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" }, { "method": "", @@ -12765,6 +15706,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -12794,6 +15736,92 @@ "wireName": "mediatype", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_1PSTICKER_AUDIO_AVATARSTICKER_CATALOGLINK_COLLECTION_DOCUMENT_GENAISTICKER_GIF_IMAGE_MOTIONPHOTO_MOTIONVIDEO_PRODUCTLINK_PTT_PTV_STICKER_STICKERPACK_URL_USERCREATEDSTICKER_VCARD_VIDEO", + "module": "WASmaxInNewslettersEnums", + "variants": [ + { + "name": "1p_sticker", + "value": "1p_sticker" + }, + { + "name": "audio", + "value": "audio" + }, + { + "name": "avatar_sticker", + "value": "avatar_sticker" + }, + { + "name": "cataloglink", + "value": "cataloglink" + }, + { + "name": "collection", + "value": "collection" + }, + { + "name": "document", + "value": "document" + }, + { + "name": "genai_sticker", + "value": "genai_sticker" + }, + { + "name": "gif", + "value": "gif" + }, + { + "name": "image", + "value": "image" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "motion_video", + "value": "motion_video" + }, + { + "name": "productlink", + "value": "productlink" + }, + { + "name": "ptt", + "value": "ptt" + }, + { + "name": "ptv", + "value": "ptv" + }, + { + "name": "sticker", + "value": "sticker" + }, + { + "name": "sticker_pack", + "value": "sticker_pack" + }, + { + "name": "url", + "value": "url" + }, + { + "name": "user_created_sticker", + "value": "user_created_sticker" + }, + { + "name": "vcard", + "value": "vcard" + }, + { + "name": "video", + "value": "video" + } + ] + }, "sourcePath": [ "plaintext" ] @@ -12821,7 +15849,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" }, { "method": "", @@ -12835,6 +15864,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -12854,6 +15884,40 @@ "wireName": "message_association_type", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_HDIMAGEDUALUPLOAD_HDVIDEODUALUPLOAD_HEVCVIDEODUALUPLOAD_MEDIAPOLL_MOTIONPHOTO_POLLADDOPTION_STICKERANNOTATION", + "module": "WASmaxInNewslettersEnums", + "variants": [ + { + "name": "hd_image_dual_upload", + "value": "hd_image_dual_upload" + }, + { + "name": "hd_video_dual_upload", + "value": "hd_video_dual_upload" + }, + { + "name": "hevc_video_dual_upload", + "value": "hevc_video_dual_upload" + }, + { + "name": "media_poll", + "value": "media_poll" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "poll_add_option", + "value": "poll_add_option" + }, + { + "name": "sticker_annotation", + "value": "sticker_annotation" + } + ] + }, "sourcePath": [ "meta" ] @@ -12911,14 +15975,16 @@ "name": "edit", "wireName": "edit", "type": "string", - "required": true + "required": true, + "literalValue": "8" }, { "method": "attrString", "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" }, { "method": "", @@ -12932,6 +15998,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -12983,7 +16050,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" }, { "method": "", @@ -12997,6 +16065,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -13026,6 +16095,92 @@ "wireName": "mediatype", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_1PSTICKER_AUDIO_AVATARSTICKER_CATALOGLINK_COLLECTION_DOCUMENT_GENAISTICKER_GIF_IMAGE_MOTIONPHOTO_MOTIONVIDEO_PRODUCTLINK_PTT_PTV_STICKER_STICKERPACK_URL_USERCREATEDSTICKER_VCARD_VIDEO", + "module": "WASmaxInNewslettersEnums", + "variants": [ + { + "name": "1p_sticker", + "value": "1p_sticker" + }, + { + "name": "audio", + "value": "audio" + }, + { + "name": "avatar_sticker", + "value": "avatar_sticker" + }, + { + "name": "cataloglink", + "value": "cataloglink" + }, + { + "name": "collection", + "value": "collection" + }, + { + "name": "document", + "value": "document" + }, + { + "name": "genai_sticker", + "value": "genai_sticker" + }, + { + "name": "gif", + "value": "gif" + }, + { + "name": "image", + "value": "image" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "motion_video", + "value": "motion_video" + }, + { + "name": "productlink", + "value": "productlink" + }, + { + "name": "ptt", + "value": "ptt" + }, + { + "name": "ptv", + "value": "ptv" + }, + { + "name": "sticker", + "value": "sticker" + }, + { + "name": "sticker_pack", + "value": "sticker_pack" + }, + { + "name": "url", + "value": "url" + }, + { + "name": "user_created_sticker", + "value": "user_created_sticker" + }, + { + "name": "vcard", + "value": "vcard" + }, + { + "name": "video", + "value": "video" + } + ] + }, "sourcePath": [ "plaintext" ] @@ -13053,7 +16208,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" }, { "method": "", @@ -13067,6 +16223,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -13086,6 +16243,40 @@ "wireName": "message_association_type", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_HDIMAGEDUALUPLOAD_HDVIDEODUALUPLOAD_HEVCVIDEODUALUPLOAD_MEDIAPOLL_MOTIONPHOTO_POLLADDOPTION_STICKERANNOTATION", + "module": "WASmaxInNewslettersEnums", + "variants": [ + { + "name": "hd_image_dual_upload", + "value": "hd_image_dual_upload" + }, + { + "name": "hd_video_dual_upload", + "value": "hd_video_dual_upload" + }, + { + "name": "hevc_video_dual_upload", + "value": "hevc_video_dual_upload" + }, + { + "name": "media_poll", + "value": "media_poll" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "poll_add_option", + "value": "poll_add_option" + }, + { + "name": "sticker_annotation", + "value": "sticker_annotation" + } + ] + }, "sourcePath": [ "meta" ] @@ -13151,7 +16342,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "poll" }, { "method": "attrString", @@ -13159,6 +16351,7 @@ "wireName": "polltype", "type": "string", "required": true, + "literalValue": "creation", "sourcePath": [ "meta" ] @@ -13185,6 +16378,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -13231,7 +16425,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "poll" }, { "method": "attrString", @@ -13239,6 +16434,7 @@ "wireName": "polltype", "type": "string", "required": true, + "literalValue": "quiz_creation", "sourcePath": [ "meta" ] @@ -13265,6 +16461,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -13311,7 +16508,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "poll" }, { "method": "attrString", @@ -13319,6 +16517,7 @@ "wireName": "polltype", "type": "string", "required": true, + "literalValue": "result_snapshot", "sourcePath": [ "meta" ] @@ -13335,6 +16534,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -13364,6 +16564,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -13379,7 +16580,8 @@ "name": "edit", "wireName": "edit", "type": "string", - "required": true + "required": true, + "literalValue": "8" } ], "sameNode": true @@ -13395,7 +16597,8 @@ "name": "edit", "wireName": "edit", "type": "string", - "required": true + "required": true, + "literalValue": "3" } ], "sameNode": true @@ -13415,6 +16618,7 @@ "wireName": "questiontype", "type": "string", "required": true, + "literalValue": "question", "sourcePath": [ "meta" ] @@ -13433,7 +16637,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" } ], "assertions": [ @@ -13456,7 +16661,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" } ], "assertions": [ @@ -13490,6 +16696,7 @@ "wireName": "questiontype", "type": "string", "required": true, + "literalValue": "reply", "sourcePath": [ "meta" ] @@ -13508,7 +16715,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" } ], "assertions": [ @@ -13531,7 +16739,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" } ], "assertions": [ @@ -13564,7 +16773,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" } ], "assertions": [ @@ -13587,7 +16797,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" } ], "assertions": [ @@ -13610,7 +16821,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "poll" }, { "method": "attrString", @@ -13618,6 +16830,7 @@ "wireName": "polltype", "type": "string", "required": true, + "literalValue": "creation", "sourcePath": [ "meta" ] @@ -13653,7 +16866,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "poll" }, { "method": "attrString", @@ -13661,6 +16875,7 @@ "wireName": "polltype", "type": "string", "required": true, + "literalValue": "quiz_creation", "sourcePath": [ "meta" ] @@ -13803,6 +17018,7 @@ "wireName": "mediatype", "type": "string", "required": true, + "literalValue": "url", "sourcePath": [ "plaintext" ] @@ -13821,7 +17037,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" } ], "sameNode": true @@ -13866,7 +17083,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": false + "required": false, + "literalValue": "views" }, { "method": "attrInt", @@ -13923,7 +17141,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ], "variants": [ @@ -13936,6 +17155,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -13999,7 +17232,8 @@ "name": "isSender", "wireName": "is_sender", "type": "string", - "required": false + "required": false, + "literalValue": "true" }, { "method": "", @@ -14134,6 +17368,7 @@ "wireName": "questiontype", "type": "string", "required": true, + "literalValue": "question", "sourcePath": [ "meta" ] @@ -14150,6 +17385,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -14189,7 +17425,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" }, { "method": "", @@ -14203,6 +17440,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -14232,6 +17470,92 @@ "wireName": "mediatype", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_1PSTICKER_AUDIO_AVATARSTICKER_CATALOGLINK_COLLECTION_DOCUMENT_GENAISTICKER_GIF_IMAGE_MOTIONPHOTO_MOTIONVIDEO_PRODUCTLINK_PTT_PTV_STICKER_STICKERPACK_URL_USERCREATEDSTICKER_VCARD_VIDEO", + "module": "WASmaxInNewslettersEnums", + "variants": [ + { + "name": "1p_sticker", + "value": "1p_sticker" + }, + { + "name": "audio", + "value": "audio" + }, + { + "name": "avatar_sticker", + "value": "avatar_sticker" + }, + { + "name": "cataloglink", + "value": "cataloglink" + }, + { + "name": "collection", + "value": "collection" + }, + { + "name": "document", + "value": "document" + }, + { + "name": "genai_sticker", + "value": "genai_sticker" + }, + { + "name": "gif", + "value": "gif" + }, + { + "name": "image", + "value": "image" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "motion_video", + "value": "motion_video" + }, + { + "name": "productlink", + "value": "productlink" + }, + { + "name": "ptt", + "value": "ptt" + }, + { + "name": "ptv", + "value": "ptv" + }, + { + "name": "sticker", + "value": "sticker" + }, + { + "name": "sticker_pack", + "value": "sticker_pack" + }, + { + "name": "url", + "value": "url" + }, + { + "name": "user_created_sticker", + "value": "user_created_sticker" + }, + { + "name": "vcard", + "value": "vcard" + }, + { + "name": "video", + "value": "video" + } + ] + }, "sourcePath": [ "plaintext" ] @@ -14259,7 +17583,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" }, { "method": "", @@ -14273,6 +17598,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -14292,6 +17618,40 @@ "wireName": "message_association_type", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_HDIMAGEDUALUPLOAD_HDVIDEODUALUPLOAD_HEVCVIDEODUALUPLOAD_MEDIAPOLL_MOTIONPHOTO_POLLADDOPTION_STICKERANNOTATION", + "module": "WASmaxInNewslettersEnums", + "variants": [ + { + "name": "hd_image_dual_upload", + "value": "hd_image_dual_upload" + }, + { + "name": "hd_video_dual_upload", + "value": "hd_video_dual_upload" + }, + { + "name": "hevc_video_dual_upload", + "value": "hevc_video_dual_upload" + }, + { + "name": "media_poll", + "value": "media_poll" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "poll_add_option", + "value": "poll_add_option" + }, + { + "name": "sticker_annotation", + "value": "sticker_annotation" + } + ] + }, "sourcePath": [ "meta" ] @@ -14349,7 +17709,8 @@ "name": "edit", "wireName": "edit", "type": "string", - "required": true + "required": true, + "literalValue": "3" }, { "method": "", @@ -14363,6 +17724,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -14385,6 +17747,7 @@ "wireName": "questiontype", "type": "string", "required": true, + "literalValue": "reply", "sourcePath": [ "meta" ] @@ -14401,6 +17764,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -14440,7 +17804,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" }, { "method": "", @@ -14454,6 +17819,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -14483,6 +17849,92 @@ "wireName": "mediatype", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_1PSTICKER_AUDIO_AVATARSTICKER_CATALOGLINK_COLLECTION_DOCUMENT_GENAISTICKER_GIF_IMAGE_MOTIONPHOTO_MOTIONVIDEO_PRODUCTLINK_PTT_PTV_STICKER_STICKERPACK_URL_USERCREATEDSTICKER_VCARD_VIDEO", + "module": "WASmaxInNewslettersEnums", + "variants": [ + { + "name": "1p_sticker", + "value": "1p_sticker" + }, + { + "name": "audio", + "value": "audio" + }, + { + "name": "avatar_sticker", + "value": "avatar_sticker" + }, + { + "name": "cataloglink", + "value": "cataloglink" + }, + { + "name": "collection", + "value": "collection" + }, + { + "name": "document", + "value": "document" + }, + { + "name": "genai_sticker", + "value": "genai_sticker" + }, + { + "name": "gif", + "value": "gif" + }, + { + "name": "image", + "value": "image" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "motion_video", + "value": "motion_video" + }, + { + "name": "productlink", + "value": "productlink" + }, + { + "name": "ptt", + "value": "ptt" + }, + { + "name": "ptv", + "value": "ptv" + }, + { + "name": "sticker", + "value": "sticker" + }, + { + "name": "sticker_pack", + "value": "sticker_pack" + }, + { + "name": "url", + "value": "url" + }, + { + "name": "user_created_sticker", + "value": "user_created_sticker" + }, + { + "name": "vcard", + "value": "vcard" + }, + { + "name": "video", + "value": "video" + } + ] + }, "sourcePath": [ "plaintext" ] @@ -14510,7 +17962,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" }, { "method": "", @@ -14524,6 +17977,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -14543,6 +17997,40 @@ "wireName": "message_association_type", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_HDIMAGEDUALUPLOAD_HDVIDEODUALUPLOAD_HEVCVIDEODUALUPLOAD_MEDIAPOLL_MOTIONPHOTO_POLLADDOPTION_STICKERANNOTATION", + "module": "WASmaxInNewslettersEnums", + "variants": [ + { + "name": "hd_image_dual_upload", + "value": "hd_image_dual_upload" + }, + { + "name": "hd_video_dual_upload", + "value": "hd_video_dual_upload" + }, + { + "name": "hevc_video_dual_upload", + "value": "hevc_video_dual_upload" + }, + { + "name": "media_poll", + "value": "media_poll" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "poll_add_option", + "value": "poll_add_option" + }, + { + "name": "sticker_annotation", + "value": "sticker_annotation" + } + ] + }, "sourcePath": [ "meta" ] @@ -14618,7 +18106,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" }, { "method": "", @@ -14632,6 +18121,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -14661,6 +18151,92 @@ "wireName": "mediatype", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_1PSTICKER_AUDIO_AVATARSTICKER_CATALOGLINK_COLLECTION_DOCUMENT_GENAISTICKER_GIF_IMAGE_MOTIONPHOTO_MOTIONVIDEO_PRODUCTLINK_PTT_PTV_STICKER_STICKERPACK_URL_USERCREATEDSTICKER_VCARD_VIDEO", + "module": "WASmaxInNewslettersEnums", + "variants": [ + { + "name": "1p_sticker", + "value": "1p_sticker" + }, + { + "name": "audio", + "value": "audio" + }, + { + "name": "avatar_sticker", + "value": "avatar_sticker" + }, + { + "name": "cataloglink", + "value": "cataloglink" + }, + { + "name": "collection", + "value": "collection" + }, + { + "name": "document", + "value": "document" + }, + { + "name": "genai_sticker", + "value": "genai_sticker" + }, + { + "name": "gif", + "value": "gif" + }, + { + "name": "image", + "value": "image" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "motion_video", + "value": "motion_video" + }, + { + "name": "productlink", + "value": "productlink" + }, + { + "name": "ptt", + "value": "ptt" + }, + { + "name": "ptv", + "value": "ptv" + }, + { + "name": "sticker", + "value": "sticker" + }, + { + "name": "sticker_pack", + "value": "sticker_pack" + }, + { + "name": "url", + "value": "url" + }, + { + "name": "user_created_sticker", + "value": "user_created_sticker" + }, + { + "name": "vcard", + "value": "vcard" + }, + { + "name": "video", + "value": "video" + } + ] + }, "sourcePath": [ "plaintext" ] @@ -14688,7 +18264,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" }, { "method": "", @@ -14702,6 +18279,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -14721,6 +18299,40 @@ "wireName": "message_association_type", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_HDIMAGEDUALUPLOAD_HDVIDEODUALUPLOAD_HEVCVIDEODUALUPLOAD_MEDIAPOLL_MOTIONPHOTO_POLLADDOPTION_STICKERANNOTATION", + "module": "WASmaxInNewslettersEnums", + "variants": [ + { + "name": "hd_image_dual_upload", + "value": "hd_image_dual_upload" + }, + { + "name": "hd_video_dual_upload", + "value": "hd_video_dual_upload" + }, + { + "name": "hevc_video_dual_upload", + "value": "hevc_video_dual_upload" + }, + { + "name": "media_poll", + "value": "media_poll" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "poll_add_option", + "value": "poll_add_option" + }, + { + "name": "sticker_annotation", + "value": "sticker_annotation" + } + ] + }, "sourcePath": [ "meta" ] @@ -14784,6 +18396,7 @@ "wireName": "questiontype", "type": "string", "required": true, + "literalValue": "reply", "sourcePath": [ "meta" ] @@ -14800,6 +18413,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -14839,7 +18453,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" }, { "method": "", @@ -14853,6 +18468,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -14882,6 +18498,92 @@ "wireName": "mediatype", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_1PSTICKER_AUDIO_AVATARSTICKER_CATALOGLINK_COLLECTION_DOCUMENT_GENAISTICKER_GIF_IMAGE_MOTIONPHOTO_MOTIONVIDEO_PRODUCTLINK_PTT_PTV_STICKER_STICKERPACK_URL_USERCREATEDSTICKER_VCARD_VIDEO", + "module": "WASmaxInNewslettersEnums", + "variants": [ + { + "name": "1p_sticker", + "value": "1p_sticker" + }, + { + "name": "audio", + "value": "audio" + }, + { + "name": "avatar_sticker", + "value": "avatar_sticker" + }, + { + "name": "cataloglink", + "value": "cataloglink" + }, + { + "name": "collection", + "value": "collection" + }, + { + "name": "document", + "value": "document" + }, + { + "name": "genai_sticker", + "value": "genai_sticker" + }, + { + "name": "gif", + "value": "gif" + }, + { + "name": "image", + "value": "image" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "motion_video", + "value": "motion_video" + }, + { + "name": "productlink", + "value": "productlink" + }, + { + "name": "ptt", + "value": "ptt" + }, + { + "name": "ptv", + "value": "ptv" + }, + { + "name": "sticker", + "value": "sticker" + }, + { + "name": "sticker_pack", + "value": "sticker_pack" + }, + { + "name": "url", + "value": "url" + }, + { + "name": "user_created_sticker", + "value": "user_created_sticker" + }, + { + "name": "vcard", + "value": "vcard" + }, + { + "name": "video", + "value": "video" + } + ] + }, "sourcePath": [ "plaintext" ] @@ -14909,7 +18611,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" }, { "method": "", @@ -14923,6 +18626,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -14942,6 +18646,40 @@ "wireName": "message_association_type", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_HDIMAGEDUALUPLOAD_HDVIDEODUALUPLOAD_HEVCVIDEODUALUPLOAD_MEDIAPOLL_MOTIONPHOTO_POLLADDOPTION_STICKERANNOTATION", + "module": "WASmaxInNewslettersEnums", + "variants": [ + { + "name": "hd_image_dual_upload", + "value": "hd_image_dual_upload" + }, + { + "name": "hd_video_dual_upload", + "value": "hd_video_dual_upload" + }, + { + "name": "hevc_video_dual_upload", + "value": "hevc_video_dual_upload" + }, + { + "name": "media_poll", + "value": "media_poll" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "poll_add_option", + "value": "poll_add_option" + }, + { + "name": "sticker_annotation", + "value": "sticker_annotation" + } + ] + }, "sourcePath": [ "meta" ] @@ -14999,14 +18737,16 @@ "name": "edit", "wireName": "edit", "type": "string", - "required": true + "required": true, + "literalValue": "8" }, { "method": "attrString", "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" }, { "method": "", @@ -15020,6 +18760,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -15071,7 +18812,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" }, { "method": "", @@ -15085,6 +18827,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -15114,6 +18857,92 @@ "wireName": "mediatype", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_1PSTICKER_AUDIO_AVATARSTICKER_CATALOGLINK_COLLECTION_DOCUMENT_GENAISTICKER_GIF_IMAGE_MOTIONPHOTO_MOTIONVIDEO_PRODUCTLINK_PTT_PTV_STICKER_STICKERPACK_URL_USERCREATEDSTICKER_VCARD_VIDEO", + "module": "WASmaxInNewslettersEnums", + "variants": [ + { + "name": "1p_sticker", + "value": "1p_sticker" + }, + { + "name": "audio", + "value": "audio" + }, + { + "name": "avatar_sticker", + "value": "avatar_sticker" + }, + { + "name": "cataloglink", + "value": "cataloglink" + }, + { + "name": "collection", + "value": "collection" + }, + { + "name": "document", + "value": "document" + }, + { + "name": "genai_sticker", + "value": "genai_sticker" + }, + { + "name": "gif", + "value": "gif" + }, + { + "name": "image", + "value": "image" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "motion_video", + "value": "motion_video" + }, + { + "name": "productlink", + "value": "productlink" + }, + { + "name": "ptt", + "value": "ptt" + }, + { + "name": "ptv", + "value": "ptv" + }, + { + "name": "sticker", + "value": "sticker" + }, + { + "name": "sticker_pack", + "value": "sticker_pack" + }, + { + "name": "url", + "value": "url" + }, + { + "name": "user_created_sticker", + "value": "user_created_sticker" + }, + { + "name": "vcard", + "value": "vcard" + }, + { + "name": "video", + "value": "video" + } + ] + }, "sourcePath": [ "plaintext" ] @@ -15141,7 +18970,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" }, { "method": "", @@ -15155,6 +18985,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -15174,6 +19005,40 @@ "wireName": "message_association_type", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_HDIMAGEDUALUPLOAD_HDVIDEODUALUPLOAD_HEVCVIDEODUALUPLOAD_MEDIAPOLL_MOTIONPHOTO_POLLADDOPTION_STICKERANNOTATION", + "module": "WASmaxInNewslettersEnums", + "variants": [ + { + "name": "hd_image_dual_upload", + "value": "hd_image_dual_upload" + }, + { + "name": "hd_video_dual_upload", + "value": "hd_video_dual_upload" + }, + { + "name": "hevc_video_dual_upload", + "value": "hevc_video_dual_upload" + }, + { + "name": "media_poll", + "value": "media_poll" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "poll_add_option", + "value": "poll_add_option" + }, + { + "name": "sticker_annotation", + "value": "sticker_annotation" + } + ] + }, "sourcePath": [ "meta" ] @@ -15239,7 +19104,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "poll" }, { "method": "attrString", @@ -15247,6 +19113,7 @@ "wireName": "polltype", "type": "string", "required": true, + "literalValue": "creation", "sourcePath": [ "meta" ] @@ -15273,6 +19140,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -15319,7 +19187,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "poll" }, { "method": "attrString", @@ -15327,6 +19196,7 @@ "wireName": "polltype", "type": "string", "required": true, + "literalValue": "quiz_creation", "sourcePath": [ "meta" ] @@ -15353,6 +19223,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -15399,7 +19270,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "poll" }, { "method": "attrString", @@ -15407,6 +19279,7 @@ "wireName": "polltype", "type": "string", "required": true, + "literalValue": "result_snapshot", "sourcePath": [ "meta" ] @@ -15423,6 +19296,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -15452,6 +19326,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -15467,7 +19342,8 @@ "name": "edit", "wireName": "edit", "type": "string", - "required": true + "required": true, + "literalValue": "8" } ], "sameNode": true @@ -15483,7 +19359,8 @@ "name": "edit", "wireName": "edit", "type": "string", - "required": true + "required": true, + "literalValue": "3" } ], "sameNode": true @@ -15503,6 +19380,7 @@ "wireName": "questiontype", "type": "string", "required": true, + "literalValue": "question", "sourcePath": [ "meta" ] @@ -15521,7 +19399,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" } ], "assertions": [ @@ -15544,7 +19423,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" } ], "assertions": [ @@ -15578,6 +19458,7 @@ "wireName": "questiontype", "type": "string", "required": true, + "literalValue": "reply", "sourcePath": [ "meta" ] @@ -15596,7 +19477,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" } ], "assertions": [ @@ -15619,7 +19501,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" } ], "assertions": [ @@ -15652,7 +19535,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" } ], "assertions": [ @@ -15675,7 +19559,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" } ], "assertions": [ @@ -15698,7 +19583,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "poll" }, { "method": "attrString", @@ -15706,6 +19592,7 @@ "wireName": "polltype", "type": "string", "required": true, + "literalValue": "creation", "sourcePath": [ "meta" ] @@ -15741,7 +19628,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "poll" }, { "method": "attrString", @@ -15749,6 +19637,7 @@ "wireName": "polltype", "type": "string", "required": true, + "literalValue": "quiz_creation", "sourcePath": [ "meta" ] @@ -15891,6 +19780,7 @@ "wireName": "mediatype", "type": "string", "required": true, + "literalValue": "url", "sourcePath": [ "plaintext" ] @@ -15909,7 +19799,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" } ], "sameNode": true @@ -15954,7 +19845,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": false + "required": false, + "literalValue": "views" }, { "method": "attrInt", @@ -16011,14 +19903,42 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ] }, { "tag": "GetNewsletterMessageUpdatesResponseClientError", "moduleName": "WASmaxInNewslettersGetNewsletterMessageUpdatesResponseClientError", - "kind": "error", + "kind": "client_error", + "errorArms": [ + { + "name": "BadRequestIQErrorResponse", + "code": 400, + "text": "bad-request" + }, + { + "name": "UnavailableForLegalReasonsResponse", + "code": 451, + "text": "features-disabled" + }, + { + "name": "ItemNotFoundIQErrorResponse", + "code": 404, + "text": "item-not-found" + }, + { + "name": "SuspendedIQErrorResponse", + "code": 423, + "text": "locked" + }, + { + "name": "RateLimitedIQErrorResponse", + "code": 429, + "text": "rate-overlimit" + } + ], "assertions": [ { "kind": "tag", @@ -16047,14 +19967,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "repeats": false @@ -16064,7 +19986,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ], "assertions": [ @@ -16072,6 +19995,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -16094,14 +20031,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "features-disabled" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "451" } ], "repeats": false @@ -16111,7 +20050,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ], "assertions": [ @@ -16119,6 +20059,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -16141,14 +20095,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "item-not-found" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "404" } ], "repeats": false @@ -16158,7 +20114,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ], "assertions": [ @@ -16166,6 +20123,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -16188,14 +20159,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "locked" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "423" } ], "repeats": false @@ -16205,7 +20178,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ], "assertions": [ @@ -16213,6 +20187,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -16235,14 +20223,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "rate-overlimit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "429" } ], "repeats": false @@ -16252,7 +20242,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ], "assertions": [ @@ -16260,6 +20251,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -16274,12 +20279,32 @@ { "tag": "GetNewsletterMessageUpdatesResponseServerError", "moduleName": "WASmaxInNewslettersGetNewsletterMessageUpdatesResponseServerError", - "kind": "error", + "kind": "server_error", + "errorArms": [ + { + "code": 500, + "text": "internal-server-error" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -16299,14 +20324,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "repeats": false @@ -16316,7 +20343,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ] } @@ -16426,7 +20454,7 @@ "assertions": [], "fields": [ { - "method": "attrJidWithType", + "method": "literalJid", "name": "from", "wireName": "from", "type": "jid", @@ -16437,7 +20465,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "child", @@ -16495,7 +20524,8 @@ "name": "isSender", "wireName": "is_sender", "type": "string", - "required": false + "required": false, + "literalValue": "true" }, { "method": "", @@ -16630,6 +20660,7 @@ "wireName": "questiontype", "type": "string", "required": true, + "literalValue": "question", "sourcePath": [ "meta" ] @@ -16646,6 +20677,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -16685,7 +20717,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" }, { "method": "", @@ -16699,6 +20732,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -16728,6 +20762,92 @@ "wireName": "mediatype", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_1PSTICKER_AUDIO_AVATARSTICKER_CATALOGLINK_COLLECTION_DOCUMENT_GENAISTICKER_GIF_IMAGE_MOTIONPHOTO_MOTIONVIDEO_PRODUCTLINK_PTT_PTV_STICKER_STICKERPACK_URL_USERCREATEDSTICKER_VCARD_VIDEO", + "module": "WASmaxInNewslettersEnums", + "variants": [ + { + "name": "1p_sticker", + "value": "1p_sticker" + }, + { + "name": "audio", + "value": "audio" + }, + { + "name": "avatar_sticker", + "value": "avatar_sticker" + }, + { + "name": "cataloglink", + "value": "cataloglink" + }, + { + "name": "collection", + "value": "collection" + }, + { + "name": "document", + "value": "document" + }, + { + "name": "genai_sticker", + "value": "genai_sticker" + }, + { + "name": "gif", + "value": "gif" + }, + { + "name": "image", + "value": "image" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "motion_video", + "value": "motion_video" + }, + { + "name": "productlink", + "value": "productlink" + }, + { + "name": "ptt", + "value": "ptt" + }, + { + "name": "ptv", + "value": "ptv" + }, + { + "name": "sticker", + "value": "sticker" + }, + { + "name": "sticker_pack", + "value": "sticker_pack" + }, + { + "name": "url", + "value": "url" + }, + { + "name": "user_created_sticker", + "value": "user_created_sticker" + }, + { + "name": "vcard", + "value": "vcard" + }, + { + "name": "video", + "value": "video" + } + ] + }, "sourcePath": [ "plaintext" ] @@ -16755,7 +20875,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" }, { "method": "", @@ -16769,6 +20890,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -16788,6 +20910,40 @@ "wireName": "message_association_type", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_HDIMAGEDUALUPLOAD_HDVIDEODUALUPLOAD_HEVCVIDEODUALUPLOAD_MEDIAPOLL_MOTIONPHOTO_POLLADDOPTION_STICKERANNOTATION", + "module": "WASmaxInNewslettersEnums", + "variants": [ + { + "name": "hd_image_dual_upload", + "value": "hd_image_dual_upload" + }, + { + "name": "hd_video_dual_upload", + "value": "hd_video_dual_upload" + }, + { + "name": "hevc_video_dual_upload", + "value": "hevc_video_dual_upload" + }, + { + "name": "media_poll", + "value": "media_poll" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "poll_add_option", + "value": "poll_add_option" + }, + { + "name": "sticker_annotation", + "value": "sticker_annotation" + } + ] + }, "sourcePath": [ "meta" ] @@ -16845,7 +21001,8 @@ "name": "edit", "wireName": "edit", "type": "string", - "required": true + "required": true, + "literalValue": "3" }, { "method": "", @@ -16859,6 +21016,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -16881,6 +21039,7 @@ "wireName": "questiontype", "type": "string", "required": true, + "literalValue": "reply", "sourcePath": [ "meta" ] @@ -16897,6 +21056,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -16936,7 +21096,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" }, { "method": "", @@ -16950,6 +21111,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -16979,6 +21141,92 @@ "wireName": "mediatype", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_1PSTICKER_AUDIO_AVATARSTICKER_CATALOGLINK_COLLECTION_DOCUMENT_GENAISTICKER_GIF_IMAGE_MOTIONPHOTO_MOTIONVIDEO_PRODUCTLINK_PTT_PTV_STICKER_STICKERPACK_URL_USERCREATEDSTICKER_VCARD_VIDEO", + "module": "WASmaxInNewslettersEnums", + "variants": [ + { + "name": "1p_sticker", + "value": "1p_sticker" + }, + { + "name": "audio", + "value": "audio" + }, + { + "name": "avatar_sticker", + "value": "avatar_sticker" + }, + { + "name": "cataloglink", + "value": "cataloglink" + }, + { + "name": "collection", + "value": "collection" + }, + { + "name": "document", + "value": "document" + }, + { + "name": "genai_sticker", + "value": "genai_sticker" + }, + { + "name": "gif", + "value": "gif" + }, + { + "name": "image", + "value": "image" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "motion_video", + "value": "motion_video" + }, + { + "name": "productlink", + "value": "productlink" + }, + { + "name": "ptt", + "value": "ptt" + }, + { + "name": "ptv", + "value": "ptv" + }, + { + "name": "sticker", + "value": "sticker" + }, + { + "name": "sticker_pack", + "value": "sticker_pack" + }, + { + "name": "url", + "value": "url" + }, + { + "name": "user_created_sticker", + "value": "user_created_sticker" + }, + { + "name": "vcard", + "value": "vcard" + }, + { + "name": "video", + "value": "video" + } + ] + }, "sourcePath": [ "plaintext" ] @@ -17006,7 +21254,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" }, { "method": "", @@ -17020,6 +21269,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -17039,6 +21289,40 @@ "wireName": "message_association_type", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_HDIMAGEDUALUPLOAD_HDVIDEODUALUPLOAD_HEVCVIDEODUALUPLOAD_MEDIAPOLL_MOTIONPHOTO_POLLADDOPTION_STICKERANNOTATION", + "module": "WASmaxInNewslettersEnums", + "variants": [ + { + "name": "hd_image_dual_upload", + "value": "hd_image_dual_upload" + }, + { + "name": "hd_video_dual_upload", + "value": "hd_video_dual_upload" + }, + { + "name": "hevc_video_dual_upload", + "value": "hevc_video_dual_upload" + }, + { + "name": "media_poll", + "value": "media_poll" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "poll_add_option", + "value": "poll_add_option" + }, + { + "name": "sticker_annotation", + "value": "sticker_annotation" + } + ] + }, "sourcePath": [ "meta" ] @@ -17114,7 +21398,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" }, { "method": "", @@ -17128,6 +21413,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -17157,6 +21443,92 @@ "wireName": "mediatype", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_1PSTICKER_AUDIO_AVATARSTICKER_CATALOGLINK_COLLECTION_DOCUMENT_GENAISTICKER_GIF_IMAGE_MOTIONPHOTO_MOTIONVIDEO_PRODUCTLINK_PTT_PTV_STICKER_STICKERPACK_URL_USERCREATEDSTICKER_VCARD_VIDEO", + "module": "WASmaxInNewslettersEnums", + "variants": [ + { + "name": "1p_sticker", + "value": "1p_sticker" + }, + { + "name": "audio", + "value": "audio" + }, + { + "name": "avatar_sticker", + "value": "avatar_sticker" + }, + { + "name": "cataloglink", + "value": "cataloglink" + }, + { + "name": "collection", + "value": "collection" + }, + { + "name": "document", + "value": "document" + }, + { + "name": "genai_sticker", + "value": "genai_sticker" + }, + { + "name": "gif", + "value": "gif" + }, + { + "name": "image", + "value": "image" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "motion_video", + "value": "motion_video" + }, + { + "name": "productlink", + "value": "productlink" + }, + { + "name": "ptt", + "value": "ptt" + }, + { + "name": "ptv", + "value": "ptv" + }, + { + "name": "sticker", + "value": "sticker" + }, + { + "name": "sticker_pack", + "value": "sticker_pack" + }, + { + "name": "url", + "value": "url" + }, + { + "name": "user_created_sticker", + "value": "user_created_sticker" + }, + { + "name": "vcard", + "value": "vcard" + }, + { + "name": "video", + "value": "video" + } + ] + }, "sourcePath": [ "plaintext" ] @@ -17184,7 +21556,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" }, { "method": "", @@ -17198,6 +21571,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -17217,6 +21591,40 @@ "wireName": "message_association_type", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_HDIMAGEDUALUPLOAD_HDVIDEODUALUPLOAD_HEVCVIDEODUALUPLOAD_MEDIAPOLL_MOTIONPHOTO_POLLADDOPTION_STICKERANNOTATION", + "module": "WASmaxInNewslettersEnums", + "variants": [ + { + "name": "hd_image_dual_upload", + "value": "hd_image_dual_upload" + }, + { + "name": "hd_video_dual_upload", + "value": "hd_video_dual_upload" + }, + { + "name": "hevc_video_dual_upload", + "value": "hevc_video_dual_upload" + }, + { + "name": "media_poll", + "value": "media_poll" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "poll_add_option", + "value": "poll_add_option" + }, + { + "name": "sticker_annotation", + "value": "sticker_annotation" + } + ] + }, "sourcePath": [ "meta" ] @@ -17280,6 +21688,7 @@ "wireName": "questiontype", "type": "string", "required": true, + "literalValue": "reply", "sourcePath": [ "meta" ] @@ -17296,6 +21705,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -17335,7 +21745,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" }, { "method": "", @@ -17349,6 +21760,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -17378,6 +21790,92 @@ "wireName": "mediatype", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_1PSTICKER_AUDIO_AVATARSTICKER_CATALOGLINK_COLLECTION_DOCUMENT_GENAISTICKER_GIF_IMAGE_MOTIONPHOTO_MOTIONVIDEO_PRODUCTLINK_PTT_PTV_STICKER_STICKERPACK_URL_USERCREATEDSTICKER_VCARD_VIDEO", + "module": "WASmaxInNewslettersEnums", + "variants": [ + { + "name": "1p_sticker", + "value": "1p_sticker" + }, + { + "name": "audio", + "value": "audio" + }, + { + "name": "avatar_sticker", + "value": "avatar_sticker" + }, + { + "name": "cataloglink", + "value": "cataloglink" + }, + { + "name": "collection", + "value": "collection" + }, + { + "name": "document", + "value": "document" + }, + { + "name": "genai_sticker", + "value": "genai_sticker" + }, + { + "name": "gif", + "value": "gif" + }, + { + "name": "image", + "value": "image" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "motion_video", + "value": "motion_video" + }, + { + "name": "productlink", + "value": "productlink" + }, + { + "name": "ptt", + "value": "ptt" + }, + { + "name": "ptv", + "value": "ptv" + }, + { + "name": "sticker", + "value": "sticker" + }, + { + "name": "sticker_pack", + "value": "sticker_pack" + }, + { + "name": "url", + "value": "url" + }, + { + "name": "user_created_sticker", + "value": "user_created_sticker" + }, + { + "name": "vcard", + "value": "vcard" + }, + { + "name": "video", + "value": "video" + } + ] + }, "sourcePath": [ "plaintext" ] @@ -17405,7 +21903,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" }, { "method": "", @@ -17419,6 +21918,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -17438,6 +21938,40 @@ "wireName": "message_association_type", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_HDIMAGEDUALUPLOAD_HDVIDEODUALUPLOAD_HEVCVIDEODUALUPLOAD_MEDIAPOLL_MOTIONPHOTO_POLLADDOPTION_STICKERANNOTATION", + "module": "WASmaxInNewslettersEnums", + "variants": [ + { + "name": "hd_image_dual_upload", + "value": "hd_image_dual_upload" + }, + { + "name": "hd_video_dual_upload", + "value": "hd_video_dual_upload" + }, + { + "name": "hevc_video_dual_upload", + "value": "hevc_video_dual_upload" + }, + { + "name": "media_poll", + "value": "media_poll" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "poll_add_option", + "value": "poll_add_option" + }, + { + "name": "sticker_annotation", + "value": "sticker_annotation" + } + ] + }, "sourcePath": [ "meta" ] @@ -17495,14 +22029,16 @@ "name": "edit", "wireName": "edit", "type": "string", - "required": true + "required": true, + "literalValue": "8" }, { "method": "attrString", "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" }, { "method": "", @@ -17516,6 +22052,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -17567,7 +22104,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" }, { "method": "", @@ -17581,6 +22119,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -17610,6 +22149,92 @@ "wireName": "mediatype", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_1PSTICKER_AUDIO_AVATARSTICKER_CATALOGLINK_COLLECTION_DOCUMENT_GENAISTICKER_GIF_IMAGE_MOTIONPHOTO_MOTIONVIDEO_PRODUCTLINK_PTT_PTV_STICKER_STICKERPACK_URL_USERCREATEDSTICKER_VCARD_VIDEO", + "module": "WASmaxInNewslettersEnums", + "variants": [ + { + "name": "1p_sticker", + "value": "1p_sticker" + }, + { + "name": "audio", + "value": "audio" + }, + { + "name": "avatar_sticker", + "value": "avatar_sticker" + }, + { + "name": "cataloglink", + "value": "cataloglink" + }, + { + "name": "collection", + "value": "collection" + }, + { + "name": "document", + "value": "document" + }, + { + "name": "genai_sticker", + "value": "genai_sticker" + }, + { + "name": "gif", + "value": "gif" + }, + { + "name": "image", + "value": "image" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "motion_video", + "value": "motion_video" + }, + { + "name": "productlink", + "value": "productlink" + }, + { + "name": "ptt", + "value": "ptt" + }, + { + "name": "ptv", + "value": "ptv" + }, + { + "name": "sticker", + "value": "sticker" + }, + { + "name": "sticker_pack", + "value": "sticker_pack" + }, + { + "name": "url", + "value": "url" + }, + { + "name": "user_created_sticker", + "value": "user_created_sticker" + }, + { + "name": "vcard", + "value": "vcard" + }, + { + "name": "video", + "value": "video" + } + ] + }, "sourcePath": [ "plaintext" ] @@ -17637,7 +22262,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" }, { "method": "", @@ -17651,6 +22277,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -17670,6 +22297,40 @@ "wireName": "message_association_type", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_HDIMAGEDUALUPLOAD_HDVIDEODUALUPLOAD_HEVCVIDEODUALUPLOAD_MEDIAPOLL_MOTIONPHOTO_POLLADDOPTION_STICKERANNOTATION", + "module": "WASmaxInNewslettersEnums", + "variants": [ + { + "name": "hd_image_dual_upload", + "value": "hd_image_dual_upload" + }, + { + "name": "hd_video_dual_upload", + "value": "hd_video_dual_upload" + }, + { + "name": "hevc_video_dual_upload", + "value": "hevc_video_dual_upload" + }, + { + "name": "media_poll", + "value": "media_poll" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "poll_add_option", + "value": "poll_add_option" + }, + { + "name": "sticker_annotation", + "value": "sticker_annotation" + } + ] + }, "sourcePath": [ "meta" ] @@ -17735,7 +22396,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "poll" }, { "method": "attrString", @@ -17743,6 +22405,7 @@ "wireName": "polltype", "type": "string", "required": true, + "literalValue": "creation", "sourcePath": [ "meta" ] @@ -17769,6 +22432,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -17815,7 +22479,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "poll" }, { "method": "attrString", @@ -17823,6 +22488,7 @@ "wireName": "polltype", "type": "string", "required": true, + "literalValue": "quiz_creation", "sourcePath": [ "meta" ] @@ -17849,6 +22515,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -17895,7 +22562,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "poll" }, { "method": "attrString", @@ -17903,6 +22571,7 @@ "wireName": "polltype", "type": "string", "required": true, + "literalValue": "result_snapshot", "sourcePath": [ "meta" ] @@ -17919,6 +22588,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -17948,6 +22618,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -17963,7 +22634,8 @@ "name": "edit", "wireName": "edit", "type": "string", - "required": true + "required": true, + "literalValue": "8" } ], "sameNode": true @@ -17979,7 +22651,8 @@ "name": "edit", "wireName": "edit", "type": "string", - "required": true + "required": true, + "literalValue": "3" } ], "sameNode": true @@ -17999,6 +22672,7 @@ "wireName": "questiontype", "type": "string", "required": true, + "literalValue": "question", "sourcePath": [ "meta" ] @@ -18017,7 +22691,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" } ], "assertions": [ @@ -18040,7 +22715,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" } ], "assertions": [ @@ -18074,6 +22750,7 @@ "wireName": "questiontype", "type": "string", "required": true, + "literalValue": "reply", "sourcePath": [ "meta" ] @@ -18092,7 +22769,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" } ], "assertions": [ @@ -18115,7 +22793,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" } ], "assertions": [ @@ -18148,7 +22827,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" } ], "assertions": [ @@ -18171,7 +22851,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" } ], "assertions": [ @@ -18194,7 +22875,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "poll" }, { "method": "attrString", @@ -18202,6 +22884,7 @@ "wireName": "polltype", "type": "string", "required": true, + "literalValue": "creation", "sourcePath": [ "meta" ] @@ -18237,7 +22920,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "poll" }, { "method": "attrString", @@ -18245,6 +22929,7 @@ "wireName": "polltype", "type": "string", "required": true, + "literalValue": "quiz_creation", "sourcePath": [ "meta" ] @@ -18387,6 +23072,7 @@ "wireName": "mediatype", "type": "string", "required": true, + "literalValue": "url", "sourcePath": [ "plaintext" ] @@ -18405,7 +23091,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" } ], "sameNode": true @@ -18450,7 +23137,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": false + "required": false, + "literalValue": "views" }, { "method": "attrInt", @@ -18510,6 +23198,13 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, { "kind": "attr", "name": "type", @@ -18518,7 +23213,7 @@ ], "fields": [ { - "method": "attrJidWithType", + "method": "literalJid", "name": "from", "wireName": "from", "type": "jid", @@ -18529,7 +23224,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "child", @@ -18587,7 +23283,8 @@ "name": "isSender", "wireName": "is_sender", "type": "string", - "required": false + "required": false, + "literalValue": "true" }, { "method": "", @@ -18722,6 +23419,7 @@ "wireName": "questiontype", "type": "string", "required": true, + "literalValue": "question", "sourcePath": [ "meta" ] @@ -18738,6 +23436,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -18777,7 +23476,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" }, { "method": "", @@ -18791,6 +23491,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -18820,6 +23521,92 @@ "wireName": "mediatype", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_1PSTICKER_AUDIO_AVATARSTICKER_CATALOGLINK_COLLECTION_DOCUMENT_GENAISTICKER_GIF_IMAGE_MOTIONPHOTO_MOTIONVIDEO_PRODUCTLINK_PTT_PTV_STICKER_STICKERPACK_URL_USERCREATEDSTICKER_VCARD_VIDEO", + "module": "WASmaxInNewslettersEnums", + "variants": [ + { + "name": "1p_sticker", + "value": "1p_sticker" + }, + { + "name": "audio", + "value": "audio" + }, + { + "name": "avatar_sticker", + "value": "avatar_sticker" + }, + { + "name": "cataloglink", + "value": "cataloglink" + }, + { + "name": "collection", + "value": "collection" + }, + { + "name": "document", + "value": "document" + }, + { + "name": "genai_sticker", + "value": "genai_sticker" + }, + { + "name": "gif", + "value": "gif" + }, + { + "name": "image", + "value": "image" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "motion_video", + "value": "motion_video" + }, + { + "name": "productlink", + "value": "productlink" + }, + { + "name": "ptt", + "value": "ptt" + }, + { + "name": "ptv", + "value": "ptv" + }, + { + "name": "sticker", + "value": "sticker" + }, + { + "name": "sticker_pack", + "value": "sticker_pack" + }, + { + "name": "url", + "value": "url" + }, + { + "name": "user_created_sticker", + "value": "user_created_sticker" + }, + { + "name": "vcard", + "value": "vcard" + }, + { + "name": "video", + "value": "video" + } + ] + }, "sourcePath": [ "plaintext" ] @@ -18847,7 +23634,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" }, { "method": "", @@ -18861,6 +23649,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -18880,6 +23669,40 @@ "wireName": "message_association_type", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_HDIMAGEDUALUPLOAD_HDVIDEODUALUPLOAD_HEVCVIDEODUALUPLOAD_MEDIAPOLL_MOTIONPHOTO_POLLADDOPTION_STICKERANNOTATION", + "module": "WASmaxInNewslettersEnums", + "variants": [ + { + "name": "hd_image_dual_upload", + "value": "hd_image_dual_upload" + }, + { + "name": "hd_video_dual_upload", + "value": "hd_video_dual_upload" + }, + { + "name": "hevc_video_dual_upload", + "value": "hevc_video_dual_upload" + }, + { + "name": "media_poll", + "value": "media_poll" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "poll_add_option", + "value": "poll_add_option" + }, + { + "name": "sticker_annotation", + "value": "sticker_annotation" + } + ] + }, "sourcePath": [ "meta" ] @@ -18937,7 +23760,8 @@ "name": "edit", "wireName": "edit", "type": "string", - "required": true + "required": true, + "literalValue": "3" }, { "method": "", @@ -18951,6 +23775,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -18973,6 +23798,7 @@ "wireName": "questiontype", "type": "string", "required": true, + "literalValue": "reply", "sourcePath": [ "meta" ] @@ -18989,6 +23815,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -19028,7 +23855,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" }, { "method": "", @@ -19042,6 +23870,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -19071,6 +23900,92 @@ "wireName": "mediatype", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_1PSTICKER_AUDIO_AVATARSTICKER_CATALOGLINK_COLLECTION_DOCUMENT_GENAISTICKER_GIF_IMAGE_MOTIONPHOTO_MOTIONVIDEO_PRODUCTLINK_PTT_PTV_STICKER_STICKERPACK_URL_USERCREATEDSTICKER_VCARD_VIDEO", + "module": "WASmaxInNewslettersEnums", + "variants": [ + { + "name": "1p_sticker", + "value": "1p_sticker" + }, + { + "name": "audio", + "value": "audio" + }, + { + "name": "avatar_sticker", + "value": "avatar_sticker" + }, + { + "name": "cataloglink", + "value": "cataloglink" + }, + { + "name": "collection", + "value": "collection" + }, + { + "name": "document", + "value": "document" + }, + { + "name": "genai_sticker", + "value": "genai_sticker" + }, + { + "name": "gif", + "value": "gif" + }, + { + "name": "image", + "value": "image" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "motion_video", + "value": "motion_video" + }, + { + "name": "productlink", + "value": "productlink" + }, + { + "name": "ptt", + "value": "ptt" + }, + { + "name": "ptv", + "value": "ptv" + }, + { + "name": "sticker", + "value": "sticker" + }, + { + "name": "sticker_pack", + "value": "sticker_pack" + }, + { + "name": "url", + "value": "url" + }, + { + "name": "user_created_sticker", + "value": "user_created_sticker" + }, + { + "name": "vcard", + "value": "vcard" + }, + { + "name": "video", + "value": "video" + } + ] + }, "sourcePath": [ "plaintext" ] @@ -19098,7 +24013,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" }, { "method": "", @@ -19112,6 +24028,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -19131,6 +24048,40 @@ "wireName": "message_association_type", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_HDIMAGEDUALUPLOAD_HDVIDEODUALUPLOAD_HEVCVIDEODUALUPLOAD_MEDIAPOLL_MOTIONPHOTO_POLLADDOPTION_STICKERANNOTATION", + "module": "WASmaxInNewslettersEnums", + "variants": [ + { + "name": "hd_image_dual_upload", + "value": "hd_image_dual_upload" + }, + { + "name": "hd_video_dual_upload", + "value": "hd_video_dual_upload" + }, + { + "name": "hevc_video_dual_upload", + "value": "hevc_video_dual_upload" + }, + { + "name": "media_poll", + "value": "media_poll" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "poll_add_option", + "value": "poll_add_option" + }, + { + "name": "sticker_annotation", + "value": "sticker_annotation" + } + ] + }, "sourcePath": [ "meta" ] @@ -19206,7 +24157,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" }, { "method": "", @@ -19220,6 +24172,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -19249,6 +24202,92 @@ "wireName": "mediatype", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_1PSTICKER_AUDIO_AVATARSTICKER_CATALOGLINK_COLLECTION_DOCUMENT_GENAISTICKER_GIF_IMAGE_MOTIONPHOTO_MOTIONVIDEO_PRODUCTLINK_PTT_PTV_STICKER_STICKERPACK_URL_USERCREATEDSTICKER_VCARD_VIDEO", + "module": "WASmaxInNewslettersEnums", + "variants": [ + { + "name": "1p_sticker", + "value": "1p_sticker" + }, + { + "name": "audio", + "value": "audio" + }, + { + "name": "avatar_sticker", + "value": "avatar_sticker" + }, + { + "name": "cataloglink", + "value": "cataloglink" + }, + { + "name": "collection", + "value": "collection" + }, + { + "name": "document", + "value": "document" + }, + { + "name": "genai_sticker", + "value": "genai_sticker" + }, + { + "name": "gif", + "value": "gif" + }, + { + "name": "image", + "value": "image" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "motion_video", + "value": "motion_video" + }, + { + "name": "productlink", + "value": "productlink" + }, + { + "name": "ptt", + "value": "ptt" + }, + { + "name": "ptv", + "value": "ptv" + }, + { + "name": "sticker", + "value": "sticker" + }, + { + "name": "sticker_pack", + "value": "sticker_pack" + }, + { + "name": "url", + "value": "url" + }, + { + "name": "user_created_sticker", + "value": "user_created_sticker" + }, + { + "name": "vcard", + "value": "vcard" + }, + { + "name": "video", + "value": "video" + } + ] + }, "sourcePath": [ "plaintext" ] @@ -19276,7 +24315,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" }, { "method": "", @@ -19290,6 +24330,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -19309,6 +24350,40 @@ "wireName": "message_association_type", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_HDIMAGEDUALUPLOAD_HDVIDEODUALUPLOAD_HEVCVIDEODUALUPLOAD_MEDIAPOLL_MOTIONPHOTO_POLLADDOPTION_STICKERANNOTATION", + "module": "WASmaxInNewslettersEnums", + "variants": [ + { + "name": "hd_image_dual_upload", + "value": "hd_image_dual_upload" + }, + { + "name": "hd_video_dual_upload", + "value": "hd_video_dual_upload" + }, + { + "name": "hevc_video_dual_upload", + "value": "hevc_video_dual_upload" + }, + { + "name": "media_poll", + "value": "media_poll" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "poll_add_option", + "value": "poll_add_option" + }, + { + "name": "sticker_annotation", + "value": "sticker_annotation" + } + ] + }, "sourcePath": [ "meta" ] @@ -19372,6 +24447,7 @@ "wireName": "questiontype", "type": "string", "required": true, + "literalValue": "reply", "sourcePath": [ "meta" ] @@ -19388,6 +24464,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -19427,7 +24504,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" }, { "method": "", @@ -19441,6 +24519,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -19470,6 +24549,92 @@ "wireName": "mediatype", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_1PSTICKER_AUDIO_AVATARSTICKER_CATALOGLINK_COLLECTION_DOCUMENT_GENAISTICKER_GIF_IMAGE_MOTIONPHOTO_MOTIONVIDEO_PRODUCTLINK_PTT_PTV_STICKER_STICKERPACK_URL_USERCREATEDSTICKER_VCARD_VIDEO", + "module": "WASmaxInNewslettersEnums", + "variants": [ + { + "name": "1p_sticker", + "value": "1p_sticker" + }, + { + "name": "audio", + "value": "audio" + }, + { + "name": "avatar_sticker", + "value": "avatar_sticker" + }, + { + "name": "cataloglink", + "value": "cataloglink" + }, + { + "name": "collection", + "value": "collection" + }, + { + "name": "document", + "value": "document" + }, + { + "name": "genai_sticker", + "value": "genai_sticker" + }, + { + "name": "gif", + "value": "gif" + }, + { + "name": "image", + "value": "image" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "motion_video", + "value": "motion_video" + }, + { + "name": "productlink", + "value": "productlink" + }, + { + "name": "ptt", + "value": "ptt" + }, + { + "name": "ptv", + "value": "ptv" + }, + { + "name": "sticker", + "value": "sticker" + }, + { + "name": "sticker_pack", + "value": "sticker_pack" + }, + { + "name": "url", + "value": "url" + }, + { + "name": "user_created_sticker", + "value": "user_created_sticker" + }, + { + "name": "vcard", + "value": "vcard" + }, + { + "name": "video", + "value": "video" + } + ] + }, "sourcePath": [ "plaintext" ] @@ -19497,7 +24662,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" }, { "method": "", @@ -19511,6 +24677,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -19530,6 +24697,40 @@ "wireName": "message_association_type", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_HDIMAGEDUALUPLOAD_HDVIDEODUALUPLOAD_HEVCVIDEODUALUPLOAD_MEDIAPOLL_MOTIONPHOTO_POLLADDOPTION_STICKERANNOTATION", + "module": "WASmaxInNewslettersEnums", + "variants": [ + { + "name": "hd_image_dual_upload", + "value": "hd_image_dual_upload" + }, + { + "name": "hd_video_dual_upload", + "value": "hd_video_dual_upload" + }, + { + "name": "hevc_video_dual_upload", + "value": "hevc_video_dual_upload" + }, + { + "name": "media_poll", + "value": "media_poll" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "poll_add_option", + "value": "poll_add_option" + }, + { + "name": "sticker_annotation", + "value": "sticker_annotation" + } + ] + }, "sourcePath": [ "meta" ] @@ -19587,14 +24788,16 @@ "name": "edit", "wireName": "edit", "type": "string", - "required": true + "required": true, + "literalValue": "8" }, { "method": "attrString", "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" }, { "method": "", @@ -19608,6 +24811,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -19659,7 +24863,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" }, { "method": "", @@ -19673,6 +24878,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -19702,6 +24908,92 @@ "wireName": "mediatype", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_1PSTICKER_AUDIO_AVATARSTICKER_CATALOGLINK_COLLECTION_DOCUMENT_GENAISTICKER_GIF_IMAGE_MOTIONPHOTO_MOTIONVIDEO_PRODUCTLINK_PTT_PTV_STICKER_STICKERPACK_URL_USERCREATEDSTICKER_VCARD_VIDEO", + "module": "WASmaxInNewslettersEnums", + "variants": [ + { + "name": "1p_sticker", + "value": "1p_sticker" + }, + { + "name": "audio", + "value": "audio" + }, + { + "name": "avatar_sticker", + "value": "avatar_sticker" + }, + { + "name": "cataloglink", + "value": "cataloglink" + }, + { + "name": "collection", + "value": "collection" + }, + { + "name": "document", + "value": "document" + }, + { + "name": "genai_sticker", + "value": "genai_sticker" + }, + { + "name": "gif", + "value": "gif" + }, + { + "name": "image", + "value": "image" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "motion_video", + "value": "motion_video" + }, + { + "name": "productlink", + "value": "productlink" + }, + { + "name": "ptt", + "value": "ptt" + }, + { + "name": "ptv", + "value": "ptv" + }, + { + "name": "sticker", + "value": "sticker" + }, + { + "name": "sticker_pack", + "value": "sticker_pack" + }, + { + "name": "url", + "value": "url" + }, + { + "name": "user_created_sticker", + "value": "user_created_sticker" + }, + { + "name": "vcard", + "value": "vcard" + }, + { + "name": "video", + "value": "video" + } + ] + }, "sourcePath": [ "plaintext" ] @@ -19729,7 +25021,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" }, { "method": "", @@ -19743,6 +25036,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -19762,6 +25056,40 @@ "wireName": "message_association_type", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_HDIMAGEDUALUPLOAD_HDVIDEODUALUPLOAD_HEVCVIDEODUALUPLOAD_MEDIAPOLL_MOTIONPHOTO_POLLADDOPTION_STICKERANNOTATION", + "module": "WASmaxInNewslettersEnums", + "variants": [ + { + "name": "hd_image_dual_upload", + "value": "hd_image_dual_upload" + }, + { + "name": "hd_video_dual_upload", + "value": "hd_video_dual_upload" + }, + { + "name": "hevc_video_dual_upload", + "value": "hevc_video_dual_upload" + }, + { + "name": "media_poll", + "value": "media_poll" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "poll_add_option", + "value": "poll_add_option" + }, + { + "name": "sticker_annotation", + "value": "sticker_annotation" + } + ] + }, "sourcePath": [ "meta" ] @@ -19827,7 +25155,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "poll" }, { "method": "attrString", @@ -19835,6 +25164,7 @@ "wireName": "polltype", "type": "string", "required": true, + "literalValue": "creation", "sourcePath": [ "meta" ] @@ -19861,6 +25191,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -19907,7 +25238,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "poll" }, { "method": "attrString", @@ -19915,6 +25247,7 @@ "wireName": "polltype", "type": "string", "required": true, + "literalValue": "quiz_creation", "sourcePath": [ "meta" ] @@ -19941,6 +25274,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -19987,7 +25321,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "poll" }, { "method": "attrString", @@ -19995,6 +25330,7 @@ "wireName": "polltype", "type": "string", "required": true, + "literalValue": "result_snapshot", "sourcePath": [ "meta" ] @@ -20011,6 +25347,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -20040,6 +25377,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -20055,7 +25393,8 @@ "name": "edit", "wireName": "edit", "type": "string", - "required": true + "required": true, + "literalValue": "8" } ], "sameNode": true @@ -20071,7 +25410,8 @@ "name": "edit", "wireName": "edit", "type": "string", - "required": true + "required": true, + "literalValue": "3" } ], "sameNode": true @@ -20091,6 +25431,7 @@ "wireName": "questiontype", "type": "string", "required": true, + "literalValue": "question", "sourcePath": [ "meta" ] @@ -20109,7 +25450,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" } ], "assertions": [ @@ -20132,7 +25474,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" } ], "assertions": [ @@ -20166,6 +25509,7 @@ "wireName": "questiontype", "type": "string", "required": true, + "literalValue": "reply", "sourcePath": [ "meta" ] @@ -20184,7 +25528,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" } ], "assertions": [ @@ -20207,7 +25552,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" } ], "assertions": [ @@ -20240,7 +25586,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" } ], "assertions": [ @@ -20263,7 +25610,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" } ], "assertions": [ @@ -20286,7 +25634,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "poll" }, { "method": "attrString", @@ -20294,6 +25643,7 @@ "wireName": "polltype", "type": "string", "required": true, + "literalValue": "creation", "sourcePath": [ "meta" ] @@ -20329,7 +25679,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "poll" }, { "method": "attrString", @@ -20337,6 +25688,7 @@ "wireName": "polltype", "type": "string", "required": true, + "literalValue": "quiz_creation", "sourcePath": [ "meta" ] @@ -20479,6 +25831,7 @@ "wireName": "mediatype", "type": "string", "required": true, + "literalValue": "url", "sourcePath": [ "plaintext" ] @@ -20497,7 +25850,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" } ], "sameNode": true @@ -20542,7 +25896,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": false + "required": false, + "literalValue": "views" }, { "method": "attrInt", @@ -20596,7 +25951,39 @@ { "tag": "GetNewsletterMessagesResponseClientError", "moduleName": "WASmaxInNewslettersGetNewsletterMessagesResponseClientError", - "kind": "error", + "kind": "client_error", + "errorArms": [ + { + "name": "BadRequestIQErrorResponse", + "code": 400, + "text": "bad-request" + }, + { + "name": "UnavailableForLegalReasonsResponse", + "code": 451, + "text": "features-disabled" + }, + { + "name": "ItemNotFoundIQErrorResponse", + "code": 404, + "text": "item-not-found" + }, + { + "name": "SuspendedIQErrorResponse", + "code": 423, + "text": "locked" + }, + { + "name": "RateLimitedIQErrorResponse", + "code": 429, + "text": "rate-overlimit" + }, + { + "name": "NotAllowedIQErrorResponse", + "code": 405, + "text": "not-allowed" + } + ], "assertions": [ { "kind": "tag", @@ -20625,14 +26012,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "repeats": false @@ -20642,7 +26031,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ], "assertions": [ @@ -20650,6 +26040,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -20672,14 +26076,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "features-disabled" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "451" } ], "repeats": false @@ -20689,7 +26095,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ], "assertions": [ @@ -20697,6 +26104,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -20719,14 +26140,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "item-not-found" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "404" } ], "repeats": false @@ -20736,7 +26159,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ], "assertions": [ @@ -20744,6 +26168,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -20766,14 +26204,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "locked" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "423" } ], "repeats": false @@ -20783,7 +26223,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ], "assertions": [ @@ -20791,6 +26232,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -20813,14 +26268,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "rate-overlimit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "429" } ], "repeats": false @@ -20830,7 +26287,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ], "assertions": [ @@ -20838,6 +26296,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -20860,14 +26332,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-allowed" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "405" } ], "repeats": false @@ -20877,7 +26351,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ], "assertions": [ @@ -20885,6 +26360,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -20899,12 +26388,25 @@ { "tag": "GetNewsletterMessagesResponseServerError", "moduleName": "WASmaxInNewslettersGetNewsletterMessagesResponseServerError", - "kind": "error", + "kind": "server_error", + "errorArms": [ + { + "code": 500, + "text": "internal-server-error" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, { "kind": "attr", "name": "type", @@ -20913,7 +26415,7 @@ ], "fields": [ { - "method": "attrJidWithType", + "method": "literalJid", "name": "from", "wireName": "from", "type": "jid", @@ -20924,7 +26426,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "child", @@ -20938,14 +26441,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "repeats": false @@ -21005,7 +26510,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "attrInt", @@ -21052,6 +26558,7 @@ "wireName": "is_sender", "type": "string", "required": false, + "literalValue": "true", "sourcePath": [ "message" ] @@ -21086,7 +26593,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" }, { "method": "attrString", @@ -21094,6 +26602,7 @@ "wireName": "questiontype", "type": "string", "required": true, + "literalValue": "response", "sourcePath": [ "meta" ] @@ -21180,6 +26689,13 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, { "kind": "attr", "name": "type", @@ -21199,7 +26715,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "attrInt", @@ -21246,6 +26763,7 @@ "wireName": "is_sender", "type": "string", "required": false, + "literalValue": "true", "sourcePath": [ "message" ] @@ -21280,7 +26798,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" }, { "method": "attrString", @@ -21288,6 +26807,7 @@ "wireName": "questiontype", "type": "string", "required": true, + "literalValue": "response", "sourcePath": [ "meta" ] @@ -21368,7 +26888,39 @@ { "tag": "GetNewsletterResponsesResponseClientError", "moduleName": "WASmaxInNewslettersGetNewsletterResponsesResponseClientError", - "kind": "error", + "kind": "client_error", + "errorArms": [ + { + "name": "BadRequestIQErrorResponse", + "code": 400, + "text": "bad-request" + }, + { + "name": "UnauthorizedIQErrorResponse", + "code": 401, + "text": "not-authorized" + }, + { + "name": "ItemNotFoundIQErrorResponse", + "code": 404, + "text": "item-not-found" + }, + { + "name": "SuspendedIQErrorResponse", + "code": 423, + "text": "locked" + }, + { + "name": "RateLimitedIQErrorResponse", + "code": 429, + "text": "rate-overlimit" + }, + { + "name": "NotAllowedIQErrorResponse", + "code": 405, + "text": "not-allowed" + } + ], "assertions": [ { "kind": "tag", @@ -21397,14 +26949,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "repeats": false @@ -21414,7 +26968,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ], "assertions": [ @@ -21422,6 +26977,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -21444,14 +27013,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-authorized" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "401" } ], "repeats": false @@ -21461,7 +27032,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ], "assertions": [ @@ -21469,6 +27041,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -21491,14 +27077,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "item-not-found" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "404" } ], "repeats": false @@ -21508,7 +27096,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ], "assertions": [ @@ -21516,6 +27105,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -21538,14 +27141,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "locked" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "423" } ], "repeats": false @@ -21555,7 +27160,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ], "assertions": [ @@ -21563,6 +27169,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -21585,14 +27205,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "rate-overlimit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "429" } ], "repeats": false @@ -21602,7 +27224,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ], "assertions": [ @@ -21610,6 +27233,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -21632,14 +27269,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-allowed" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "405" } ], "repeats": false @@ -21649,7 +27288,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ], "assertions": [ @@ -21657,6 +27297,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -21671,12 +27325,25 @@ { "tag": "GetNewsletterResponsesResponseServerError", "moduleName": "WASmaxInNewslettersGetNewsletterResponsesResponseServerError", - "kind": "error", + "kind": "server_error", + "errorArms": [ + { + "code": 500, + "text": "internal-server-error" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, { "kind": "attr", "name": "type", @@ -21696,7 +27363,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "child", @@ -21710,14 +27378,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "repeats": false @@ -21821,7 +27491,8 @@ "name": "isSender", "wireName": "is_sender", "type": "string", - "required": false + "required": false, + "literalValue": "true" }, { "method": "", @@ -21843,14 +27514,16 @@ "name": "edit", "wireName": "edit", "type": "string", - "required": true + "required": true, + "literalValue": "8" }, { "method": "attrString", "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" } ], "assertions": [ @@ -21896,7 +27569,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" } ], "assertions": [ @@ -21920,6 +27594,28 @@ "wireName": "mediatype", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_AUDIO_GIF_IMAGE_VIDEO", + "module": "WASmaxInNewslettersEnums", + "variants": [ + { + "name": "audio", + "value": "audio" + }, + { + "name": "gif", + "value": "gif" + }, + { + "name": "image", + "value": "image" + }, + { + "name": "video", + "value": "video" + } + ] + }, "sourcePath": [ "plaintext" ] @@ -21947,7 +27643,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" } ], "assertions": [ @@ -21980,7 +27677,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "reaction" } ], "assertions": [ @@ -22003,14 +27701,16 @@ "name": "edit", "wireName": "edit", "type": "string", - "required": true + "required": true, + "literalValue": "7" }, { "method": "attrString", "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "reaction" } ], "assertions": [ @@ -22117,6 +27817,7 @@ "wireName": "interaction_type", "type": "string", "required": true, + "literalValue": "question", "sourcePath": [ "meta" ] @@ -22136,6 +27837,7 @@ "wireName": "interaction_type", "type": "string", "required": true, + "literalValue": "question_reshare", "sourcePath": [ "meta" ] @@ -22213,6 +27915,7 @@ "wireName": "type", "type": "string", "required": true, + "literalValue": "views", "sourcePath": [ "views_count" ] @@ -22263,7 +27966,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ], "variants": [ @@ -22276,6 +27980,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -22339,7 +28057,8 @@ "name": "isSender", "wireName": "is_sender", "type": "string", - "required": false + "required": false, + "literalValue": "true" }, { "method": "", @@ -22361,14 +28080,16 @@ "name": "edit", "wireName": "edit", "type": "string", - "required": true + "required": true, + "literalValue": "8" }, { "method": "attrString", "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" } ], "assertions": [ @@ -22414,7 +28135,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" } ], "assertions": [ @@ -22438,6 +28160,28 @@ "wireName": "mediatype", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_AUDIO_GIF_IMAGE_VIDEO", + "module": "WASmaxInNewslettersEnums", + "variants": [ + { + "name": "audio", + "value": "audio" + }, + { + "name": "gif", + "value": "gif" + }, + { + "name": "image", + "value": "image" + }, + { + "name": "video", + "value": "video" + } + ] + }, "sourcePath": [ "plaintext" ] @@ -22465,7 +28209,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" } ], "assertions": [ @@ -22498,7 +28243,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "reaction" } ], "assertions": [ @@ -22521,14 +28267,16 @@ "name": "edit", "wireName": "edit", "type": "string", - "required": true + "required": true, + "literalValue": "7" }, { "method": "attrString", "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "reaction" } ], "assertions": [ @@ -22635,6 +28383,7 @@ "wireName": "interaction_type", "type": "string", "required": true, + "literalValue": "question", "sourcePath": [ "meta" ] @@ -22654,6 +28403,7 @@ "wireName": "interaction_type", "type": "string", "required": true, + "literalValue": "question_reshare", "sourcePath": [ "meta" ] @@ -22731,6 +28481,7 @@ "wireName": "type", "type": "string", "required": true, + "literalValue": "views", "sourcePath": [ "views_count" ] @@ -22781,14 +28532,42 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ] }, { "tag": "GetNewsletterStatusUpdatesResponseClientError", "moduleName": "WASmaxInNewslettersGetNewsletterStatusUpdatesResponseClientError", - "kind": "error", + "kind": "client_error", + "errorArms": [ + { + "name": "BadRequestIQErrorResponse", + "code": 400, + "text": "bad-request" + }, + { + "name": "UnavailableForLegalReasonsResponse", + "code": 451, + "text": "features-disabled" + }, + { + "name": "ItemNotFoundIQErrorResponse", + "code": 404, + "text": "item-not-found" + }, + { + "name": "SuspendedIQErrorResponse", + "code": 423, + "text": "locked" + }, + { + "name": "RateLimitedIQErrorResponse", + "code": 429, + "text": "rate-overlimit" + } + ], "assertions": [ { "kind": "tag", @@ -22817,14 +28596,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "repeats": false @@ -22834,7 +28615,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ], "assertions": [ @@ -22842,6 +28624,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -22864,14 +28660,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "features-disabled" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "451" } ], "repeats": false @@ -22881,7 +28679,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ], "assertions": [ @@ -22889,6 +28688,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -22911,14 +28724,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "item-not-found" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "404" } ], "repeats": false @@ -22928,7 +28743,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ], "assertions": [ @@ -22936,6 +28752,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -22958,14 +28788,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "locked" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "423" } ], "repeats": false @@ -22975,7 +28807,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ], "assertions": [ @@ -22983,6 +28816,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -23005,14 +28852,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "rate-overlimit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "429" } ], "repeats": false @@ -23022,7 +28871,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ], "assertions": [ @@ -23030,6 +28880,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -23044,12 +28908,32 @@ { "tag": "GetNewsletterStatusUpdatesResponseServerError", "moduleName": "WASmaxInNewslettersGetNewsletterStatusUpdatesResponseServerError", - "kind": "error", + "kind": "server_error", + "errorArms": [ + { + "code": 500, + "text": "internal-server-error" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -23069,14 +28953,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "repeats": false @@ -23086,7 +28972,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ] } @@ -23196,7 +29083,7 @@ "assertions": [], "fields": [ { - "method": "attrJidWithType", + "method": "literalJid", "name": "from", "wireName": "from", "type": "jid", @@ -23207,7 +29094,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "child", @@ -23265,7 +29153,8 @@ "name": "isSender", "wireName": "is_sender", "type": "string", - "required": false + "required": false, + "literalValue": "true" }, { "method": "", @@ -23287,14 +29176,16 @@ "name": "edit", "wireName": "edit", "type": "string", - "required": true + "required": true, + "literalValue": "8" }, { "method": "attrString", "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" } ], "assertions": [ @@ -23340,7 +29231,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" } ], "assertions": [ @@ -23364,6 +29256,28 @@ "wireName": "mediatype", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_AUDIO_GIF_IMAGE_VIDEO", + "module": "WASmaxInNewslettersEnums", + "variants": [ + { + "name": "audio", + "value": "audio" + }, + { + "name": "gif", + "value": "gif" + }, + { + "name": "image", + "value": "image" + }, + { + "name": "video", + "value": "video" + } + ] + }, "sourcePath": [ "plaintext" ] @@ -23391,7 +29305,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" } ], "assertions": [ @@ -23424,7 +29339,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "reaction" } ], "assertions": [ @@ -23447,14 +29363,16 @@ "name": "edit", "wireName": "edit", "type": "string", - "required": true + "required": true, + "literalValue": "7" }, { "method": "attrString", "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "reaction" } ], "assertions": [ @@ -23561,6 +29479,7 @@ "wireName": "interaction_type", "type": "string", "required": true, + "literalValue": "question", "sourcePath": [ "meta" ] @@ -23580,6 +29499,7 @@ "wireName": "interaction_type", "type": "string", "required": true, + "literalValue": "question_reshare", "sourcePath": [ "meta" ] @@ -23657,6 +29577,7 @@ "wireName": "type", "type": "string", "required": true, + "literalValue": "views", "sourcePath": [ "views_count" ] @@ -23710,6 +29631,13 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, { "kind": "attr", "name": "type", @@ -23718,7 +29646,7 @@ ], "fields": [ { - "method": "attrJidWithType", + "method": "literalJid", "name": "from", "wireName": "from", "type": "jid", @@ -23729,7 +29657,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "child", @@ -23787,7 +29716,8 @@ "name": "isSender", "wireName": "is_sender", "type": "string", - "required": false + "required": false, + "literalValue": "true" }, { "method": "", @@ -23809,14 +29739,16 @@ "name": "edit", "wireName": "edit", "type": "string", - "required": true + "required": true, + "literalValue": "8" }, { "method": "attrString", "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" } ], "assertions": [ @@ -23862,7 +29794,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" } ], "assertions": [ @@ -23886,6 +29819,28 @@ "wireName": "mediatype", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_AUDIO_GIF_IMAGE_VIDEO", + "module": "WASmaxInNewslettersEnums", + "variants": [ + { + "name": "audio", + "value": "audio" + }, + { + "name": "gif", + "value": "gif" + }, + { + "name": "image", + "value": "image" + }, + { + "name": "video", + "value": "video" + } + ] + }, "sourcePath": [ "plaintext" ] @@ -23913,7 +29868,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" } ], "assertions": [ @@ -23946,7 +29902,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "reaction" } ], "assertions": [ @@ -23969,14 +29926,16 @@ "name": "edit", "wireName": "edit", "type": "string", - "required": true + "required": true, + "literalValue": "7" }, { "method": "attrString", "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "reaction" } ], "assertions": [ @@ -24083,6 +30042,7 @@ "wireName": "interaction_type", "type": "string", "required": true, + "literalValue": "question", "sourcePath": [ "meta" ] @@ -24102,6 +30062,7 @@ "wireName": "interaction_type", "type": "string", "required": true, + "literalValue": "question_reshare", "sourcePath": [ "meta" ] @@ -24179,6 +30140,7 @@ "wireName": "type", "type": "string", "required": true, + "literalValue": "views", "sourcePath": [ "views_count" ] @@ -24226,7 +30188,39 @@ { "tag": "GetNewsletterStatusesResponseClientError", "moduleName": "WASmaxInNewslettersGetNewsletterStatusesResponseClientError", - "kind": "error", + "kind": "client_error", + "errorArms": [ + { + "name": "BadRequestIQErrorResponse", + "code": 400, + "text": "bad-request" + }, + { + "name": "UnavailableForLegalReasonsResponse", + "code": 451, + "text": "features-disabled" + }, + { + "name": "ItemNotFoundIQErrorResponse", + "code": 404, + "text": "item-not-found" + }, + { + "name": "SuspendedIQErrorResponse", + "code": 423, + "text": "locked" + }, + { + "name": "RateLimitedIQErrorResponse", + "code": 429, + "text": "rate-overlimit" + }, + { + "name": "NotAllowedIQErrorResponse", + "code": 405, + "text": "not-allowed" + } + ], "assertions": [ { "kind": "tag", @@ -24255,14 +30249,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "repeats": false @@ -24272,7 +30268,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ], "assertions": [ @@ -24280,6 +30277,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -24302,14 +30313,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "features-disabled" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "451" } ], "repeats": false @@ -24319,7 +30332,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ], "assertions": [ @@ -24327,6 +30341,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -24349,14 +30377,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "item-not-found" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "404" } ], "repeats": false @@ -24366,7 +30396,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ], "assertions": [ @@ -24374,6 +30405,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -24396,14 +30441,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "locked" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "423" } ], "repeats": false @@ -24413,7 +30460,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ], "assertions": [ @@ -24421,6 +30469,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -24443,14 +30505,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "rate-overlimit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "429" } ], "repeats": false @@ -24460,7 +30524,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ], "assertions": [ @@ -24468,6 +30533,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -24490,14 +30569,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-allowed" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "405" } ], "repeats": false @@ -24507,7 +30588,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ], "assertions": [ @@ -24515,6 +30597,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -24529,12 +30625,25 @@ { "tag": "GetNewsletterStatusesResponseServerError", "moduleName": "WASmaxInNewslettersGetNewsletterStatusesResponseServerError", - "kind": "error", + "kind": "server_error", + "errorArms": [ + { + "code": 500, + "text": "internal-server-error" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, { "kind": "attr", "name": "type", @@ -24543,7 +30652,7 @@ ], "fields": [ { - "method": "attrJidWithType", + "method": "literalJid", "name": "from", "wireName": "from", "type": "jid", @@ -24554,7 +30663,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "child", @@ -24568,14 +30678,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "repeats": false @@ -24628,7 +30740,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "child", @@ -24748,6 +30861,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -24760,7 +30887,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "child", @@ -24874,7 +31002,29 @@ { "tag": "MyAddOnsResponseClientError", "moduleName": "WASmaxInNewslettersMyAddOnsResponseClientError", - "kind": "error", + "kind": "client_error", + "errorArms": [ + { + "name": "BadRequestIQErrorResponse", + "code": 400, + "text": "bad-request" + }, + { + "name": "UnauthorizedIQErrorResponse", + "code": 401, + "text": "not-authorized" + }, + { + "name": "ItemNotFoundIQErrorResponse", + "code": 404, + "text": "item-not-found" + }, + { + "name": "RateLimitedIQErrorResponse", + "code": 429, + "text": "rate-overlimit" + } + ], "assertions": [ { "kind": "tag", @@ -24903,14 +31053,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "repeats": false @@ -24920,7 +31072,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ], "assertions": [ @@ -24928,6 +31081,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -24950,14 +31117,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-authorized" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "401" } ], "repeats": false @@ -24967,7 +31136,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ], "assertions": [ @@ -24975,6 +31145,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -24997,14 +31181,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "item-not-found" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "404" } ], "repeats": false @@ -25014,7 +31200,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ], "assertions": [ @@ -25022,6 +31209,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -25044,14 +31245,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "rate-overlimit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "429" } ], "repeats": false @@ -25061,7 +31264,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ], "assertions": [ @@ -25069,6 +31273,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -25083,12 +31301,32 @@ { "tag": "MyAddOnsResponseServerError", "moduleName": "WASmaxInNewslettersMyAddOnsResponseServerError", - "kind": "error", + "kind": "server_error", + "errorArms": [ + { + "code": 500, + "text": "internal-server-error" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -25108,14 +31346,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "repeats": false @@ -25125,7 +31365,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ] } @@ -25182,6 +31423,7 @@ "wireName": "type", "type": "string", "required": true, + "literalValue": "status", "sourcePath": [ "my_addons" ] @@ -25191,7 +31433,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "child", @@ -25272,6 +31515,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -25285,6 +31542,7 @@ "wireName": "type", "type": "string", "required": true, + "literalValue": "status", "sourcePath": [ "my_addons" ] @@ -25294,7 +31552,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "child", @@ -25369,7 +31628,29 @@ { "tag": "StatusMyAddOnsResponseClientError", "moduleName": "WASmaxInNewslettersStatusMyAddOnsResponseClientError", - "kind": "error", + "kind": "client_error", + "errorArms": [ + { + "name": "BadRequestIQErrorResponse", + "code": 400, + "text": "bad-request" + }, + { + "name": "UnauthorizedIQErrorResponse", + "code": 401, + "text": "not-authorized" + }, + { + "name": "ItemNotFoundIQErrorResponse", + "code": 404, + "text": "item-not-found" + }, + { + "name": "RateLimitedIQErrorResponse", + "code": 429, + "text": "rate-overlimit" + } + ], "assertions": [ { "kind": "tag", @@ -25398,14 +31679,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "repeats": false @@ -25415,7 +31698,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ], "assertions": [ @@ -25423,6 +31707,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -25445,14 +31743,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-authorized" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "401" } ], "repeats": false @@ -25462,7 +31762,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ], "assertions": [ @@ -25470,6 +31771,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -25492,14 +31807,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "item-not-found" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "404" } ], "repeats": false @@ -25509,7 +31826,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ], "assertions": [ @@ -25517,6 +31835,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -25539,14 +31871,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "rate-overlimit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "429" } ], "repeats": false @@ -25556,7 +31890,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ], "assertions": [ @@ -25564,6 +31899,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -25578,12 +31927,32 @@ { "tag": "StatusMyAddOnsResponseServerError", "moduleName": "WASmaxInNewslettersStatusMyAddOnsResponseServerError", - "kind": "error", + "kind": "server_error", + "errorArms": [ + { + "code": 500, + "text": "internal-server-error" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -25603,14 +31972,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "repeats": false @@ -25620,7 +31991,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ] } @@ -25671,7 +32043,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ], "variants": [ @@ -25684,6 +32057,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -25708,14 +32095,42 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ] }, { "tag": "SubscribeToLiveUpdatesResponseClientError", "moduleName": "WASmaxInNewslettersSubscribeToLiveUpdatesResponseClientError", - "kind": "error", + "kind": "client_error", + "errorArms": [ + { + "name": "BadRequestIQErrorResponse", + "code": 400, + "text": "bad-request" + }, + { + "name": "UnavailableForLegalReasonsResponse", + "code": 451, + "text": "features-disabled" + }, + { + "name": "ItemNotFoundIQErrorResponse", + "code": 404, + "text": "item-not-found" + }, + { + "name": "SuspendedIQErrorResponse", + "code": 423, + "text": "locked" + }, + { + "name": "RateLimitedIQErrorResponse", + "code": 429, + "text": "rate-overlimit" + } + ], "assertions": [ { "kind": "tag", @@ -25744,14 +32159,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "repeats": false @@ -25761,7 +32178,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ], "assertions": [ @@ -25769,6 +32187,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -25791,14 +32223,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "features-disabled" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "451" } ], "repeats": false @@ -25808,7 +32242,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ], "assertions": [ @@ -25816,6 +32251,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -25838,14 +32287,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "item-not-found" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "404" } ], "repeats": false @@ -25855,7 +32306,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ], "assertions": [ @@ -25863,6 +32315,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -25885,14 +32351,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "locked" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "423" } ], "repeats": false @@ -25902,7 +32370,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ], "assertions": [ @@ -25910,6 +32379,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -25932,14 +32415,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "rate-overlimit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "429" } ], "repeats": false @@ -25949,7 +32434,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ], "assertions": [ @@ -25957,6 +32443,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -25971,12 +32471,32 @@ { "tag": "SubscribeToLiveUpdatesResponseServerError", "moduleName": "WASmaxInNewslettersSubscribeToLiveUpdatesResponseServerError", - "kind": "error", + "kind": "server_error", + "errorArms": [ + { + "code": 500, + "text": "internal-server-error" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -25996,14 +32516,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "repeats": false @@ -26013,7 +32535,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ] } @@ -26059,7 +32582,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "maybeAttrString", @@ -26155,10 +32679,24 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", "value": "result" + }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] } ], "fields": [ @@ -26167,7 +32705,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "maybeAttrString", @@ -26263,10 +32802,24 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", "value": "result" + }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] } ], "fields": [ @@ -26275,26 +32828,56 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "", "name": "hasCategory", "wireName": "category", "type": "bool", - "required": true + "required": true, + "referencePath": [ + "category" + ] } ] }, { "tag": "GetOptOutListResponseInvalidRequest", "moduleName": "WASmaxInBlocklistsGetOptOutListResponseInvalidRequest", - "kind": "error", + "kind": "client_error", + "errorArms": [ + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorRateOverlimit", + "code": 429, + "text": "rate-overlimit" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -26307,7 +32890,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -26323,14 +32907,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -26342,6 +32928,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -26353,14 +32944,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "rate-overlimit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "429" } ], "assertions": [ @@ -26372,6 +32965,11 @@ "kind": "attr", "name": "text", "value": "rate-overlimit" + }, + { + "kind": "attr", + "name": "code", + "value": "429" } ] } @@ -26385,12 +32983,38 @@ { "tag": "GetOptOutListResponseInternalServerError", "moduleName": "WASmaxInBlocklistsGetOptOutListResponseInternalServerError", - "kind": "error", + "kind": "server_error", + "errorArms": [ + { + "name": "IQErrorFeatureNotImplemented", + "code": 501, + "text": "feature-not-implemented" + }, + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -26403,7 +33027,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -26419,14 +33044,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "feature-not-implemented" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "501" } ], "assertions": [ @@ -26438,6 +33065,11 @@ "kind": "attr", "name": "text", "value": "feature-not-implemented" + }, + { + "kind": "attr", + "name": "code", + "value": "501" } ] }, @@ -26449,14 +33081,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -26468,6 +33102,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] } @@ -26554,7 +33193,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "attrString", @@ -26562,6 +33202,7 @@ "wireName": "matched", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "list" ] @@ -26660,10 +33301,24 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", "value": "result" + }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] } ], "fields": [ @@ -26672,7 +33327,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "attrString", @@ -26680,6 +33336,7 @@ "wireName": "matched", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "list" ] @@ -26778,10 +33435,24 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", "value": "result" + }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] } ], "fields": [ @@ -26790,7 +33461,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "attrString", @@ -26798,6 +33470,7 @@ "wireName": "matched", "type": "string", "required": true, + "literalValue": "false", "sourcePath": [ "list" ] @@ -26807,7 +33480,14 @@ "name": "hasListCDhash", "wireName": "c_dhash", "type": "bool", - "required": true + "required": true, + "referencePath": [ + "item", + "dhash" + ], + "sourcePath": [ + "list" + ] }, { "method": "attrString", @@ -26897,12 +33577,48 @@ { "tag": "UpdateOptOutListResponseInvalidRequest", "moduleName": "WASmaxInBlocklistsUpdateOptOutListResponseInvalidRequest", - "kind": "error", + "kind": "client_error", + "errorArms": [ + { + "name": "IQErrorNotAcceptable", + "code": 406, + "text": "not-acceptable" + }, + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorForbidden", + "code": 403, + "text": "forbidden" + }, + { + "name": "IQErrorRateOverlimit", + "code": 429, + "text": "rate-overlimit" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -26915,7 +33631,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -26931,14 +33648,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-acceptable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "406" }, { "method": "child", @@ -26974,6 +33693,11 @@ "kind": "attr", "name": "text", "value": "not-acceptable" + }, + { + "kind": "attr", + "name": "code", + "value": "406" } ] }, @@ -26985,14 +33709,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -27004,6 +33730,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -27015,14 +33746,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "forbidden" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "403" } ], "assertions": [ @@ -27034,6 +33767,11 @@ "kind": "attr", "name": "text", "value": "forbidden" + }, + { + "kind": "attr", + "name": "code", + "value": "403" } ] }, @@ -27045,14 +33783,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "rate-overlimit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "429" } ], "assertions": [ @@ -27064,6 +33804,11 @@ "kind": "attr", "name": "text", "value": "rate-overlimit" + }, + { + "kind": "attr", + "name": "code", + "value": "429" } ] } @@ -27077,12 +33822,38 @@ { "tag": "UpdateOptOutListResponseServerError", "moduleName": "WASmaxInBlocklistsUpdateOptOutListResponseServerError", - "kind": "error", + "kind": "server_error", + "errorArms": [ + { + "name": "IQErrorFeatureNotImplemented", + "code": 501, + "text": "feature-not-implemented" + }, + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -27095,7 +33866,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -27111,14 +33883,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "feature-not-implemented" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "501" } ], "assertions": [ @@ -27130,6 +33904,11 @@ "kind": "attr", "name": "text", "value": "feature-not-implemented" + }, + { + "kind": "attr", + "name": "code", + "value": "501" } ] }, @@ -27141,14 +33920,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -27160,6 +33941,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] } @@ -27205,10 +33991,11 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { - "method": "attrJidWithType", + "method": "literalJid", "name": "from", "wireName": "from", "type": "jid", @@ -27225,6 +34012,13 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, { "kind": "attr", "name": "type", @@ -27237,10 +34031,11 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { - "method": "attrJidWithType", + "method": "literalJid", "name": "from", "wireName": "from", "type": "jid", @@ -27283,10 +34078,11 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { - "method": "attrJidWithType", + "method": "literalJid", "name": "from", "wireName": "from", "type": "jid", @@ -27303,6 +34099,13 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, { "kind": "attr", "name": "type", @@ -27315,10 +34118,11 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { - "method": "attrJidWithType", + "method": "literalJid", "name": "from", "wireName": "from", "type": "jid", @@ -27362,15 +34166,16 @@ "wireName": "addressing_mode", "type": "string", "required": true, + "literalValue": "lid", "sourcePath": [ "privacy" ] }, { - "method": "attrJidWithType", + "method": "attrJidEnum", "name": "from", "wireName": "from", - "type": "jid", + "type": "jid_typed", "required": false }, { @@ -27378,7 +34183,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "child", @@ -27464,6 +34270,13 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, { "kind": "attr", "name": "type", @@ -27477,15 +34290,16 @@ "wireName": "addressing_mode", "type": "string", "required": true, + "literalValue": "lid", "sourcePath": [ "privacy" ] }, { - "method": "attrJidWithType", + "method": "attrJidEnum", "name": "from", "wireName": "from", - "type": "jid", + "type": "jid_typed", "required": false }, { @@ -27493,7 +34307,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "child", @@ -27579,6 +34394,13 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, { "kind": "attr", "name": "type", @@ -27592,15 +34414,16 @@ "wireName": "addressing_mode", "type": "string", "required": false, + "literalValue": "pn", "sourcePath": [ "privacy" ] }, { - "method": "attrJidWithType", + "method": "attrJidEnum", "name": "from", "wireName": "from", - "type": "jid", + "type": "jid_typed", "required": false }, { @@ -27608,7 +34431,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "child", @@ -27660,11 +34484,45 @@ "tag": "GetContactBlacklistResponseError", "moduleName": "WASmaxInPrivacyGetContactBlacklistResponseError", "kind": "error", + "errorArms": [ + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorFeatureNotImplemented", + "code": 501, + "text": "feature-not-implemented" + }, + { + "name": "IQErrorServiceUnavailable", + "code": 503, + "text": "service-unavailable" + }, + { + "name": "IQErrorRateOverlimit", + "code": 429, + "text": "rate-overlimit" + }, + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, { "kind": "attr", "name": "type", @@ -27673,10 +34531,10 @@ ], "fields": [ { - "method": "attrJidWithType", + "method": "attrJidEnum", "name": "from", "wireName": "from", - "type": "jid", + "type": "jid_typed", "required": false }, { @@ -27684,7 +34542,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -27700,14 +34559,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -27719,6 +34580,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -27730,14 +34596,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "feature-not-implemented" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "501" } ], "assertions": [ @@ -27749,6 +34617,11 @@ "kind": "attr", "name": "text", "value": "feature-not-implemented" + }, + { + "kind": "attr", + "name": "code", + "value": "501" } ] }, @@ -27760,14 +34633,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "assertions": [ @@ -27779,6 +34654,11 @@ "kind": "attr", "name": "text", "value": "service-unavailable" + }, + { + "kind": "attr", + "name": "code", + "value": "503" } ] }, @@ -27790,14 +34670,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "rate-overlimit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "429" } ], "assertions": [ @@ -27809,6 +34691,11 @@ "kind": "attr", "name": "text", "value": "rate-overlimit" + }, + { + "kind": "attr", + "name": "code", + "value": "429" } ] }, @@ -27820,14 +34707,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -27839,6 +34728,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] } @@ -28010,61 +34904,89 @@ { "method": "attrEnum", "name": "value", - "type": "string", + "type": "enum", "required": true }, { "method": "attrEnum", "name": "value", - "type": "string", + "type": "enum", "required": true }, { "method": "attrEnum", "name": "value", - "type": "string", + "type": "enum", "required": true }, { "method": "attrEnum", "name": "value", - "type": "string", + "type": "enum", "required": true }, { "method": "attrEnum", "name": "value", - "type": "string", + "type": "enum", "required": true }, { "method": "attrEnum", "name": "value", - "type": "string", + "type": "enum", "required": true }, { "method": "attrEnum", "name": "value", - "type": "string", + "type": "enum", "required": true }, { "method": "attrEnum", "name": "value", - "type": "string", - "required": true + "type": "enum", + "required": true, + "enumRef": { + "name": "ALL_CONTACTS", + "module": "WAWebPrivacySettings", + "variants": [ + { + "name": "all", + "value": "all" + }, + { + "name": "contacts", + "value": "contacts" + } + ] + } }, { "method": "attrEnum", "name": "value", - "type": "string", - "required": true + "type": "enum", + "required": true, + "enumRef": { + "name": "DEFENSE_MODE_STATE", + "module": "WAWebPrivacySettings", + "variants": [ + { + "name": "off", + "value": "off" + }, + { + "name": "on_standard", + "value": "on_standard" + } + ] + } }, { "method": "attrEnum", "name": "value", - "type": "string", + "type": "enum", "required": true } ], @@ -28081,61 +35003,89 @@ { "method": "attrEnum", "name": "value", - "type": "string", + "type": "enum", "required": true }, { "method": "attrEnum", "name": "value", - "type": "string", + "type": "enum", "required": true }, { "method": "attrEnum", "name": "value", - "type": "string", + "type": "enum", "required": true }, { "method": "attrEnum", "name": "value", - "type": "string", + "type": "enum", "required": true }, { "method": "attrEnum", "name": "value", - "type": "string", + "type": "enum", "required": true }, { "method": "attrEnum", "name": "value", - "type": "string", + "type": "enum", "required": true }, { "method": "attrEnum", "name": "value", - "type": "string", + "type": "enum", "required": true }, { "method": "attrEnum", "name": "value", - "type": "string", - "required": true + "type": "enum", + "required": true, + "enumRef": { + "name": "ALL_CONTACTS", + "module": "WAWebPrivacySettings", + "variants": [ + { + "name": "all", + "value": "all" + }, + { + "name": "contacts", + "value": "contacts" + } + ] + } }, { "method": "attrEnum", "name": "value", - "type": "string", - "required": true + "type": "enum", + "required": true, + "enumRef": { + "name": "DEFENSE_MODE_STATE", + "module": "WAWebPrivacySettings", + "variants": [ + { + "name": "off", + "value": "off" + }, + { + "name": "on_standard", + "value": "on_standard" + } + ] + } }, { "method": "attrEnum", "name": "value", - "type": "string", + "type": "enum", "required": true } ] @@ -28536,7 +35486,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "attrInt", @@ -28615,10 +35566,24 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, { "kind": "attr", "name": "type", "value": "result" + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] } ], "fields": [ @@ -28627,7 +35592,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "attrInt", @@ -28701,11 +35667,42 @@ "tag": "SignCredentialResponseErrorNoRetry", "moduleName": "WASmaxInPrivatestatsSignCredentialResponseErrorNoRetry", "kind": "error", + "errorArms": [ + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorFeatureNotImplemented", + "code": 501, + "text": "feature-not-implemented" + }, + { + "name": "IQErrorServiceUnavailable", + "code": 503, + "text": "service-unavailable" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -28718,7 +35715,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -28734,14 +35732,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -28753,6 +35753,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -28764,14 +35769,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "feature-not-implemented" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "501" } ], "assertions": [ @@ -28783,6 +35790,11 @@ "kind": "attr", "name": "text", "value": "feature-not-implemented" + }, + { + "kind": "attr", + "name": "code", + "value": "501" } ] }, @@ -28794,14 +35806,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "assertions": [ @@ -28813,6 +35827,11 @@ "kind": "attr", "name": "text", "value": "service-unavailable" + }, + { + "kind": "attr", + "name": "code", + "value": "503" } ] } @@ -28826,12 +35845,32 @@ { "tag": "SignCredentialResponseErrorRetry", "moduleName": "WASmaxInPrivatestatsSignCredentialResponseErrorRetry", - "kind": "error", + "kind": "server_error", + "errorArms": [ + { + "code": 500, + "text": "internal-server-error" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -28851,14 +35890,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "repeats": false @@ -28868,7 +35909,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ] } @@ -29035,10 +36077,10 @@ "assertions": [], "fields": [ { - "method": "attrJidWithType", + "method": "attrJidEnum", "name": "from", "wireName": "from", - "type": "jid", + "type": "jid_typed", "required": false }, { @@ -29046,7 +36088,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "", @@ -29078,6 +36121,13 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, { "kind": "attr", "name": "type", @@ -29086,10 +36136,10 @@ ], "fields": [ { - "method": "attrJidWithType", + "method": "attrJidEnum", "name": "from", "wireName": "from", - "type": "jid", + "type": "jid_typed", "required": false }, { @@ -29097,7 +36147,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "", @@ -29124,11 +36175,49 @@ "tag": "GroupReportResponseError", "moduleName": "WASmaxInSpamGroupReportResponseError", "kind": "error", + "errorArms": [ + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorForbidden", + "code": 403, + "text": "forbidden" + }, + { + "name": "IQErrorRateOverlimit", + "code": 429, + "text": "rate-overlimit" + }, + { + "name": "IQErrorReportTokenValidationFail", + "code": 548 + }, + { + "name": "IQErrorFeatureNotImplemented", + "code": 501, + "text": "feature-not-implemented" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, { "kind": "attr", "name": "type", @@ -29137,10 +36226,10 @@ ], "fields": [ { - "method": "attrJidWithType", + "method": "attrJidEnum", "name": "from", "wireName": "from", - "type": "jid", + "type": "jid_typed", "required": false }, { @@ -29148,7 +36237,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -29164,14 +36254,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -29183,6 +36275,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -29194,14 +36291,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -29213,6 +36312,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -29224,14 +36328,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "forbidden" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "403" } ], "assertions": [ @@ -29243,6 +36349,11 @@ "kind": "attr", "name": "text", "value": "forbidden" + }, + { + "kind": "attr", + "name": "code", + "value": "403" } ] }, @@ -29254,14 +36365,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "rate-overlimit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "429" } ], "assertions": [ @@ -29273,6 +36386,11 @@ "kind": "attr", "name": "text", "value": "rate-overlimit" + }, + { + "kind": "attr", + "name": "code", + "value": "429" } ] }, @@ -29291,13 +36409,19 @@ "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "548" } ], "assertions": [ { "kind": "tag", "name": "error" + }, + { + "kind": "attr", + "name": "code", + "value": "548" } ] }, @@ -29309,14 +36433,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "feature-not-implemented" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "501" } ], "assertions": [ @@ -29328,6 +36454,11 @@ "kind": "attr", "name": "text", "value": "feature-not-implemented" + }, + { + "kind": "attr", + "name": "code", + "value": "501" } ] } @@ -29408,10 +36539,10 @@ "assertions": [], "fields": [ { - "method": "attrJidWithType", + "method": "attrJidEnum", "name": "from", "wireName": "from", - "type": "jid", + "type": "jid_typed", "required": false }, { @@ -29419,7 +36550,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "", @@ -29451,6 +36583,13 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, { "kind": "attr", "name": "type", @@ -29459,10 +36598,10 @@ ], "fields": [ { - "method": "attrJidWithType", + "method": "attrJidEnum", "name": "from", "wireName": "from", - "type": "jid", + "type": "jid_typed", "required": false }, { @@ -29470,7 +36609,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "", @@ -29497,11 +36637,49 @@ "tag": "IndividualReportResponseError", "moduleName": "WASmaxInSpamIndividualReportResponseError", "kind": "error", + "errorArms": [ + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorForbidden", + "code": 403, + "text": "forbidden" + }, + { + "name": "IQErrorRateOverlimit", + "code": 429, + "text": "rate-overlimit" + }, + { + "name": "IQErrorReportTokenValidationFail", + "code": 548 + }, + { + "name": "IQErrorFeatureNotImplemented", + "code": 501, + "text": "feature-not-implemented" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, { "kind": "attr", "name": "type", @@ -29510,10 +36688,10 @@ ], "fields": [ { - "method": "attrJidWithType", + "method": "attrJidEnum", "name": "from", "wireName": "from", - "type": "jid", + "type": "jid_typed", "required": false }, { @@ -29521,7 +36699,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -29537,14 +36716,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -29556,6 +36737,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -29567,14 +36753,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -29586,6 +36774,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -29597,14 +36790,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "forbidden" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "403" } ], "assertions": [ @@ -29616,6 +36811,11 @@ "kind": "attr", "name": "text", "value": "forbidden" + }, + { + "kind": "attr", + "name": "code", + "value": "403" } ] }, @@ -29627,14 +36827,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "rate-overlimit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "429" } ], "assertions": [ @@ -29646,6 +36848,11 @@ "kind": "attr", "name": "text", "value": "rate-overlimit" + }, + { + "kind": "attr", + "name": "code", + "value": "429" } ] }, @@ -29664,13 +36871,19 @@ "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "548" } ], "assertions": [ { "kind": "tag", "name": "error" + }, + { + "kind": "attr", + "name": "code", + "value": "548" } ] }, @@ -29682,14 +36895,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "feature-not-implemented" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "501" } ], "assertions": [ @@ -29701,6 +36916,11 @@ "kind": "attr", "name": "text", "value": "feature-not-implemented" + }, + { + "kind": "attr", + "name": "code", + "value": "501" } ] } @@ -29772,10 +36992,10 @@ "assertions": [], "fields": [ { - "method": "attrJidWithType", + "method": "attrJidEnum", "name": "from", "wireName": "from", - "type": "jid", + "type": "jid_typed", "required": false }, { @@ -29783,7 +37003,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "", @@ -29815,6 +37036,13 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, { "kind": "attr", "name": "type", @@ -29823,10 +37051,10 @@ ], "fields": [ { - "method": "attrJidWithType", + "method": "attrJidEnum", "name": "from", "wireName": "from", - "type": "jid", + "type": "jid_typed", "required": false }, { @@ -29834,7 +37062,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "", @@ -29861,11 +37090,49 @@ "tag": "NewsletterReportResponseError", "moduleName": "WASmaxInSpamNewsletterReportResponseError", "kind": "error", + "errorArms": [ + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorForbidden", + "code": 403, + "text": "forbidden" + }, + { + "name": "IQErrorRateOverlimit", + "code": 429, + "text": "rate-overlimit" + }, + { + "name": "IQErrorReportTokenValidationFail", + "code": 548 + }, + { + "name": "IQErrorFeatureNotImplemented", + "code": 501, + "text": "feature-not-implemented" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, { "kind": "attr", "name": "type", @@ -29874,10 +37141,10 @@ ], "fields": [ { - "method": "attrJidWithType", + "method": "attrJidEnum", "name": "from", "wireName": "from", - "type": "jid", + "type": "jid_typed", "required": false }, { @@ -29885,7 +37152,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -29901,14 +37169,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -29920,6 +37190,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -29931,14 +37206,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -29950,6 +37227,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -29961,14 +37243,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "forbidden" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "403" } ], "assertions": [ @@ -29980,6 +37264,11 @@ "kind": "attr", "name": "text", "value": "forbidden" + }, + { + "kind": "attr", + "name": "code", + "value": "403" } ] }, @@ -29991,14 +37280,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "rate-overlimit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "429" } ], "assertions": [ @@ -30010,6 +37301,11 @@ "kind": "attr", "name": "text", "value": "rate-overlimit" + }, + { + "kind": "attr", + "name": "code", + "value": "429" } ] }, @@ -30028,13 +37324,19 @@ "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "548" } ], "assertions": [ { "kind": "tag", "name": "error" + }, + { + "kind": "attr", + "name": "code", + "value": "548" } ] }, @@ -30046,14 +37348,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "feature-not-implemented" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "501" } ], "assertions": [ @@ -30065,6 +37369,11 @@ "kind": "attr", "name": "text", "value": "feature-not-implemented" + }, + { + "kind": "attr", + "name": "code", + "value": "501" } ] } @@ -30130,10 +37439,10 @@ "assertions": [], "fields": [ { - "method": "attrJidWithType", + "method": "attrJidEnum", "name": "from", "wireName": "from", - "type": "jid", + "type": "jid_typed", "required": false }, { @@ -30141,7 +37450,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "", @@ -30173,6 +37483,13 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, { "kind": "attr", "name": "type", @@ -30181,10 +37498,10 @@ ], "fields": [ { - "method": "attrJidWithType", + "method": "attrJidEnum", "name": "from", "wireName": "from", - "type": "jid", + "type": "jid_typed", "required": false }, { @@ -30192,7 +37509,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "", @@ -30219,11 +37537,49 @@ "tag": "StatusReportResponseError", "moduleName": "WASmaxInSpamStatusReportResponseError", "kind": "error", + "errorArms": [ + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorForbidden", + "code": 403, + "text": "forbidden" + }, + { + "name": "IQErrorRateOverlimit", + "code": 429, + "text": "rate-overlimit" + }, + { + "name": "IQErrorReportTokenValidationFail", + "code": 548 + }, + { + "name": "IQErrorFeatureNotImplemented", + "code": 501, + "text": "feature-not-implemented" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, { "kind": "attr", "name": "type", @@ -30232,10 +37588,10 @@ ], "fields": [ { - "method": "attrJidWithType", + "method": "attrJidEnum", "name": "from", "wireName": "from", - "type": "jid", + "type": "jid_typed", "required": false }, { @@ -30243,7 +37599,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -30259,14 +37616,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -30278,6 +37637,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -30289,14 +37653,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -30308,6 +37674,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -30319,14 +37690,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "forbidden" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "403" } ], "assertions": [ @@ -30338,6 +37711,11 @@ "kind": "attr", "name": "text", "value": "forbidden" + }, + { + "kind": "attr", + "name": "code", + "value": "403" } ] }, @@ -30349,14 +37727,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "rate-overlimit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "429" } ], "assertions": [ @@ -30368,6 +37748,11 @@ "kind": "attr", "name": "text", "value": "rate-overlimit" + }, + { + "kind": "attr", + "name": "code", + "value": "429" } ] }, @@ -30386,13 +37771,19 @@ "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "548" } ], "assertions": [ { "kind": "tag", "name": "error" + }, + { + "kind": "attr", + "name": "code", + "value": "548" } ] }, @@ -30404,14 +37795,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "feature-not-implemented" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "501" } ], "assertions": [ @@ -30423,6 +37816,11 @@ "kind": "attr", "name": "text", "value": "feature-not-implemented" + }, + { + "kind": "attr", + "name": "code", + "value": "501" } ] } @@ -30482,7 +37880,7 @@ "assertions": [], "fields": [ { - "method": "attrJidWithType", + "method": "attrDomainJid", "name": "from", "wireName": "from", "type": "jid", @@ -30493,7 +37891,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "", @@ -30525,6 +37924,13 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, { "kind": "attr", "name": "type", @@ -30533,7 +37939,7 @@ ], "fields": [ { - "method": "attrJidWithType", + "method": "attrDomainJid", "name": "from", "wireName": "from", "type": "jid", @@ -30544,7 +37950,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "", @@ -30571,11 +37978,40 @@ "tag": "StatusReportV2ResponseError", "moduleName": "WASmaxInSpamStatusReportV2ResponseError", "kind": "error", + "errorArms": [ + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorForbidden", + "code": 403, + "text": "forbidden" + }, + { + "name": "IQErrorRateOverlimit", + "code": 429, + "text": "rate-overlimit" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, { "kind": "attr", "name": "type", @@ -30584,7 +38020,7 @@ ], "fields": [ { - "method": "attrJidWithType", + "method": "attrDomainJid", "name": "from", "wireName": "from", "type": "jid", @@ -30595,7 +38031,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -30611,14 +38048,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -30630,6 +38069,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -30641,14 +38085,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -30660,6 +38106,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -30671,14 +38122,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "forbidden" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "403" } ], "assertions": [ @@ -30690,6 +38143,11 @@ "kind": "attr", "name": "text", "value": "forbidden" + }, + { + "kind": "attr", + "name": "code", + "value": "403" } ] }, @@ -30701,14 +38159,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "rate-overlimit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "429" } ], "assertions": [ @@ -30720,6 +38180,11 @@ "kind": "attr", "name": "text", "value": "rate-overlimit" + }, + { + "kind": "attr", + "name": "code", + "value": "429" } ] } @@ -30819,7 +38284,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "child", @@ -30879,6 +38345,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -30891,7 +38371,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "child", @@ -30945,12 +38426,32 @@ { "tag": "GetDisclosureStageByIdsResponseClientError", "moduleName": "WASmaxInUserNoticeGetDisclosureStageByIdsResponseClientError", - "kind": "error", + "kind": "client_error", + "errorArms": [ + { + "code": 400, + "text": "bad-request" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -30970,14 +38471,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "repeats": false @@ -30987,7 +38490,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ] }, @@ -30995,11 +38499,37 @@ "tag": "GetDisclosureStageByIdsResponseServerError", "moduleName": "WASmaxInUserNoticeGetDisclosureStageByIdsResponseServerError", "kind": "error", + "errorArms": [ + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorRateOverlimit", + "code": 429, + "text": "rate-overlimit" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -31012,7 +38542,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -31028,14 +38559,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -31047,6 +38580,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -31058,14 +38596,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "rate-overlimit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "429" } ], "assertions": [ @@ -31077,6 +38617,11 @@ "kind": "attr", "name": "text", "value": "rate-overlimit" + }, + { + "kind": "attr", + "name": "code", + "value": "429" } ] } @@ -31128,7 +38673,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "child", @@ -31188,6 +38734,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -31200,7 +38760,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "child", @@ -31254,12 +38815,32 @@ { "tag": "GetDisclosuresResponseClientError", "moduleName": "WASmaxInUserNoticeGetDisclosuresResponseClientError", - "kind": "error", + "kind": "client_error", + "errorArms": [ + { + "code": 400, + "text": "bad-request" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -31279,14 +38860,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "repeats": false @@ -31296,7 +38879,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ] }, @@ -31304,11 +38888,37 @@ "tag": "GetDisclosuresResponseServerError", "moduleName": "WASmaxInUserNoticeGetDisclosuresResponseServerError", "kind": "error", + "errorArms": [ + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorRateOverlimit", + "code": 429, + "text": "rate-overlimit" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -31321,7 +38931,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -31337,14 +38948,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -31356,6 +38969,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -31367,14 +38985,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "rate-overlimit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "429" } ], "assertions": [ @@ -31386,6 +39006,11 @@ "kind": "attr", "name": "text", "value": "rate-overlimit" + }, + { + "kind": "attr", + "name": "code", + "value": "429" } ] } @@ -31525,6 +39150,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -31537,7 +39176,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "child", @@ -31620,6 +39260,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -31632,7 +39286,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "child", @@ -31944,6 +39599,7 @@ "wireName": "outage", "type": "string", "required": false, + "literalValue": "1", "sourcePath": [ "accept_pay" ] @@ -31954,6 +39610,7 @@ "wireName": "sandbox", "type": "string", "required": false, + "literalValue": "1", "sourcePath": [ "accept_pay" ] @@ -31963,7 +39620,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "", @@ -31979,7 +39637,8 @@ "name": "service", "wireName": "service", "type": "string", - "required": true + "required": true, + "literalValue": "FBPAY" }, { "method": "child", @@ -31993,7 +39652,29 @@ "name": "notice", "wireName": "notice", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_BRP2PCONSENT_BRPAYPRIVACYPOLICY_BRPAYTOS_BRPAYWATOS", + "module": "WASmaxInAccountEnums", + "variants": [ + { + "name": "br_p2p_consent", + "value": "br_p2p_consent" + }, + { + "name": "br_pay_privacy_policy", + "value": "br_pay_privacy_policy" + }, + { + "name": "br_pay_tos", + "value": "br_pay_tos" + }, + { + "name": "br_pay_wa_tos", + "value": "br_pay_wa_tos" + } + ] + } } ], "repeats": true @@ -32019,7 +39700,8 @@ "name": "service", "wireName": "service", "type": "string", - "required": true + "required": true, + "literalValue": "UPI" }, { "method": "child", @@ -32033,7 +39715,21 @@ "name": "notice", "wireName": "notice", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_PAYTOSV3_UPIPAYPRIVACYPOLICY", + "module": "WASmaxInAccountEnums", + "variants": [ + { + "name": "pay_tos_v3", + "value": "pay_tos_v3" + }, + { + "name": "upi_pay_privacy_policy", + "value": "upi_pay_privacy_policy" + } + ] + } } ], "repeats": true @@ -32067,6 +39763,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -32080,6 +39790,7 @@ "wireName": "outage", "type": "string", "required": false, + "literalValue": "1", "sourcePath": [ "accept_pay" ] @@ -32090,6 +39801,7 @@ "wireName": "sandbox", "type": "string", "required": false, + "literalValue": "1", "sourcePath": [ "accept_pay" ] @@ -32099,7 +39811,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "", @@ -32115,7 +39828,8 @@ "name": "service", "wireName": "service", "type": "string", - "required": true + "required": true, + "literalValue": "FBPAY" }, { "method": "child", @@ -32129,7 +39843,29 @@ "name": "notice", "wireName": "notice", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_BRP2PCONSENT_BRPAYPRIVACYPOLICY_BRPAYTOS_BRPAYWATOS", + "module": "WASmaxInAccountEnums", + "variants": [ + { + "name": "br_p2p_consent", + "value": "br_p2p_consent" + }, + { + "name": "br_pay_privacy_policy", + "value": "br_pay_privacy_policy" + }, + { + "name": "br_pay_tos", + "value": "br_pay_tos" + }, + { + "name": "br_pay_wa_tos", + "value": "br_pay_wa_tos" + } + ] + } } ], "repeats": true @@ -32155,7 +39891,8 @@ "name": "service", "wireName": "service", "type": "string", - "required": true + "required": true, + "literalValue": "UPI" }, { "method": "child", @@ -32169,7 +39906,21 @@ "name": "notice", "wireName": "notice", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_PAYTOSV3_UPIPAYPRIVACYPOLICY", + "module": "WASmaxInAccountEnums", + "variants": [ + { + "name": "pay_tos_v3", + "value": "pay_tos_v3" + }, + { + "name": "upi_pay_privacy_policy", + "value": "upi_pay_privacy_policy" + } + ] + } } ], "repeats": true @@ -32198,11 +39949,57 @@ "tag": "SetPaymentsTOSv3ResponseError", "moduleName": "WASmaxInAccountSetPaymentsTOSv3ResponseError", "kind": "error", + "errorArms": [ + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorServiceUnavailable", + "code": 503, + "text": "service-unavailable" + }, + { + "name": "IQErrorPayUpgradeRequired", + "code": 443, + "text": "upgrade-required" + }, + { + "name": "IQErrorConfigMismatch", + "code": 453, + "text": "config-mismatch" + }, + { + "name": "IQErrorForbidden", + "code": 403, + "text": "forbidden" + }, + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -32215,7 +40012,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -32231,14 +40029,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -32250,6 +40050,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -32261,14 +40066,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "assertions": [ @@ -32280,6 +40087,11 @@ "kind": "attr", "name": "text", "value": "service-unavailable" + }, + { + "kind": "attr", + "name": "code", + "value": "503" } ] }, @@ -32291,14 +40103,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "upgrade-required" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "443" } ], "assertions": [ @@ -32310,6 +40124,11 @@ "kind": "attr", "name": "text", "value": "upgrade-required" + }, + { + "kind": "attr", + "name": "code", + "value": "443" } ] }, @@ -32321,14 +40140,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "config-mismatch" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "453" } ], "assertions": [ @@ -32340,6 +40161,11 @@ "kind": "attr", "name": "text", "value": "config-mismatch" + }, + { + "kind": "attr", + "name": "code", + "value": "453" } ] }, @@ -32351,14 +40177,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "forbidden" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "403" } ], "assertions": [ @@ -32370,6 +40198,11 @@ "kind": "attr", "name": "text", "value": "forbidden" + }, + { + "kind": "attr", + "name": "code", + "value": "403" } ] }, @@ -32381,14 +40214,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -32400,6 +40235,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] } @@ -32876,7 +40716,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ], "variants": [ @@ -32889,6 +40730,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -32901,19 +40756,40 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ] }, { "tag": "SetResponseInternalServerError", "moduleName": "WASmaxInPushConfigSetResponseInternalServerError", - "kind": "error", + "kind": "server_error", + "errorArms": [ + { + "code": 500, + "text": "internal-server-error" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -32933,14 +40809,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "repeats": false @@ -32950,19 +40828,40 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ] }, { "tag": "SetResponseConflict", "moduleName": "WASmaxInPushConfigSetResponseConflict", - "kind": "error", + "kind": "client_error", + "errorArms": [ + { + "code": 409, + "text": "conflict" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -32982,14 +40881,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "conflict" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "409" } ], "repeats": false @@ -32999,7 +40900,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ] } @@ -33461,7 +41363,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "child", @@ -33475,14 +41378,42 @@ "name": "status", "wireName": "status", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_FAIL_SUCCESS", + "module": "WASmaxInBizMarketingMessageEnums", + "variants": [ + { + "name": "FAIL", + "value": "FAIL" + }, + { + "name": "SUCCESS", + "value": "SUCCESS" + } + ] + } }, { "method": "maybeAttrEnum", "name": "shouldShowPrivacyInterstitialToNewUsers", "wireName": "should_show_privacy_interstitial_to_new_users", "type": "enum", - "required": false + "required": false, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInBizMarketingMessageEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + } }, { "method": "maybeAttrString", @@ -33506,7 +41437,29 @@ "name": "status", "wireName": "status", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_FAIL_PAUSED_SUCCESS_WARNING", + "module": "WASmaxInBizMarketingMessageEnums", + "variants": [ + { + "name": "FAIL", + "value": "FAIL" + }, + { + "name": "PAUSED", + "value": "PAUSED" + }, + { + "name": "SUCCESS", + "value": "SUCCESS" + }, + { + "name": "WARNING", + "value": "WARNING" + } + ] + } }, { "method": "maybeAttrInt", @@ -33530,14 +41483,42 @@ "name": "status", "wireName": "status", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_FAIL_SUCCESS", + "module": "WASmaxInBizMarketingMessageEnums", + "variants": [ + { + "name": "FAIL", + "value": "FAIL" + }, + { + "name": "SUCCESS", + "value": "SUCCESS" + } + ] + } }, { "method": "maybeAttrEnum", "name": "v1Enabled", "wireName": "v1_enabled", "type": "enum", - "required": false + "required": false, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInBizMarketingMessageEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + } } ], "repeats": false @@ -33554,7 +41535,21 @@ "name": "status", "wireName": "status", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_FAIL_SUCCESS", + "module": "WASmaxInBizMarketingMessageEnums", + "variants": [ + { + "name": "FAIL", + "value": "FAIL" + }, + { + "name": "SUCCESS", + "value": "SUCCESS" + } + ] + } } ], "repeats": false @@ -33571,7 +41566,21 @@ "name": "status", "wireName": "status", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_FAIL_SUCCESS", + "module": "WASmaxInBizMarketingMessageEnums", + "variants": [ + { + "name": "FAIL", + "value": "FAIL" + }, + { + "name": "SUCCESS", + "value": "SUCCESS" + } + ] + } } ], "repeats": false @@ -33588,7 +41597,25 @@ "name": "status", "wireName": "status", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_ELIGIBLETOONBOARD_NOTELIGIBLE_ONBOARDED", + "module": "WASmaxInBizMarketingMessageEnums", + "variants": [ + { + "name": "ELIGIBLE_TO_ONBOARD", + "value": "ELIGIBLE_TO_ONBOARD" + }, + { + "name": "NOT_ELIGIBLE", + "value": "NOT_ELIGIBLE" + }, + { + "name": "ONBOARDED", + "value": "ONBOARDED" + } + ] + } } ], "repeats": false @@ -33604,6 +41631,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -33623,7 +41664,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "child", @@ -33637,14 +41679,42 @@ "name": "status", "wireName": "status", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_FAIL_SUCCESS", + "module": "WASmaxInBizMarketingMessageEnums", + "variants": [ + { + "name": "FAIL", + "value": "FAIL" + }, + { + "name": "SUCCESS", + "value": "SUCCESS" + } + ] + } }, { "method": "maybeAttrEnum", "name": "shouldShowPrivacyInterstitialToNewUsers", "wireName": "should_show_privacy_interstitial_to_new_users", "type": "enum", - "required": false + "required": false, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInBizMarketingMessageEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + } }, { "method": "maybeAttrString", @@ -33668,7 +41738,29 @@ "name": "status", "wireName": "status", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_FAIL_PAUSED_SUCCESS_WARNING", + "module": "WASmaxInBizMarketingMessageEnums", + "variants": [ + { + "name": "FAIL", + "value": "FAIL" + }, + { + "name": "PAUSED", + "value": "PAUSED" + }, + { + "name": "SUCCESS", + "value": "SUCCESS" + }, + { + "name": "WARNING", + "value": "WARNING" + } + ] + } }, { "method": "maybeAttrInt", @@ -33692,14 +41784,42 @@ "name": "status", "wireName": "status", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_FAIL_SUCCESS", + "module": "WASmaxInBizMarketingMessageEnums", + "variants": [ + { + "name": "FAIL", + "value": "FAIL" + }, + { + "name": "SUCCESS", + "value": "SUCCESS" + } + ] + } }, { "method": "maybeAttrEnum", "name": "v1Enabled", "wireName": "v1_enabled", "type": "enum", - "required": false + "required": false, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInBizMarketingMessageEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + } } ], "repeats": false @@ -33716,7 +41836,21 @@ "name": "status", "wireName": "status", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_FAIL_SUCCESS", + "module": "WASmaxInBizMarketingMessageEnums", + "variants": [ + { + "name": "FAIL", + "value": "FAIL" + }, + { + "name": "SUCCESS", + "value": "SUCCESS" + } + ] + } } ], "repeats": false @@ -33733,7 +41867,21 @@ "name": "status", "wireName": "status", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_FAIL_SUCCESS", + "module": "WASmaxInBizMarketingMessageEnums", + "variants": [ + { + "name": "FAIL", + "value": "FAIL" + }, + { + "name": "SUCCESS", + "value": "SUCCESS" + } + ] + } } ], "repeats": false @@ -33750,7 +41898,25 @@ "name": "status", "wireName": "status", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_ELIGIBLETOONBOARD_NOTELIGIBLE_ONBOARDED", + "module": "WASmaxInBizMarketingMessageEnums", + "variants": [ + { + "name": "ELIGIBLE_TO_ONBOARD", + "value": "ELIGIBLE_TO_ONBOARD" + }, + { + "name": "NOT_ELIGIBLE", + "value": "NOT_ELIGIBLE" + }, + { + "name": "ONBOARDED", + "value": "ONBOARDED" + } + ] + } } ], "repeats": false @@ -33761,11 +41927,47 @@ "tag": "GetBusinessEligibilityResponseError", "moduleName": "WASmaxInBizMarketingMessageGetBusinessEligibilityResponseError", "kind": "error", + "errorArms": [ + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorForbidden", + "code": 403, + "text": "forbidden" + }, + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorServiceUnavailable", + "code": 503, + "text": "service-unavailable" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -33785,7 +41987,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -33801,14 +42004,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -33820,6 +42025,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -33831,14 +42041,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "forbidden" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "403" } ], "assertions": [ @@ -33850,6 +42062,11 @@ "kind": "attr", "name": "text", "value": "forbidden" + }, + { + "kind": "attr", + "name": "code", + "value": "403" } ] }, @@ -33861,14 +42078,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -33880,6 +42099,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -33891,14 +42115,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "assertions": [ @@ -33910,6 +42136,11 @@ "kind": "attr", "name": "text", "value": "service-unavailable" + }, + { + "kind": "attr", + "name": "code", + "value": "503" } ] } @@ -33963,6 +42194,24 @@ "wireName": "value", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_FALSE_NOTSET_TRUE", + "module": "WASmaxInBizSettingsEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "notset", + "value": "notset" + }, + { + "name": "true", + "value": "true" + } + ] + }, "sourcePath": [ "smb_data_sharing_with_meta_consent" ] @@ -33985,7 +42234,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ], "variants": [ @@ -33998,6 +42248,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -34018,6 +42282,24 @@ "wireName": "value", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_FALSE_NOTSET_TRUE", + "module": "WASmaxInBizSettingsEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "notset", + "value": "notset" + }, + { + "name": "true", + "value": "true" + } + ] + }, "sourcePath": [ "smb_data_sharing_with_meta_consent" ] @@ -34040,7 +42322,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ] }, @@ -34048,11 +42331,47 @@ "tag": "GetPrivacySettingResponseError", "moduleName": "WASmaxInBizSettingsGetPrivacySettingResponseError", "kind": "error", + "errorArms": [ + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorFeatureNotImplemented", + "code": 501, + "text": "feature-not-implemented" + }, + { + "name": "IQErrorServiceUnavailable", + "code": 503, + "text": "service-unavailable" + }, + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -34065,7 +42384,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -34081,14 +42401,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -34100,6 +42422,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -34111,14 +42438,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "feature-not-implemented" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "501" } ], "assertions": [ @@ -34130,6 +42459,11 @@ "kind": "attr", "name": "text", "value": "feature-not-implemented" + }, + { + "kind": "attr", + "name": "code", + "value": "501" } ] }, @@ -34141,14 +42475,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "assertions": [ @@ -34160,6 +42496,11 @@ "kind": "attr", "name": "text", "value": "service-unavailable" + }, + { + "kind": "attr", + "name": "code", + "value": "503" } ] }, @@ -34171,14 +42512,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -34190,6 +42533,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] } @@ -34393,6 +42741,20 @@ "wireName": "is_eligible", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInSmbMeteredMessagingAccountEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + }, "sourcePath": [ "integrity" ] @@ -34439,7 +42801,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "child", @@ -34460,7 +42823,21 @@ "name": "type", "wireName": "type", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_FREEMSG_PERCENTAGE", + "module": "WASmaxInSmbMeteredMessagingAccountEnums", + "variants": [ + { + "name": "free_msg", + "value": "free_msg" + }, + { + "name": "percentage", + "value": "percentage" + } + ] + } }, { "method": "maybeAttrInt", @@ -34542,7 +42919,37 @@ "name": "value", "wireName": "value", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_ALREADYCLAIMED_EXPIRED_INVALID_NOTFOUND_NOTOWNED_VALID", + "module": "WASmaxInSmbMeteredMessagingAccountEnums", + "variants": [ + { + "name": "already_claimed", + "value": "already_claimed" + }, + { + "name": "expired", + "value": "expired" + }, + { + "name": "invalid", + "value": "invalid" + }, + { + "name": "not_found", + "value": "not_found" + }, + { + "name": "not_owned", + "value": "not_owned" + }, + { + "name": "valid", + "value": "valid" + } + ] + } } ], "repeats": false @@ -34558,6 +42965,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -34661,6 +43082,20 @@ "wireName": "is_eligible", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInSmbMeteredMessagingAccountEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + }, "sourcePath": [ "integrity" ] @@ -34707,7 +43142,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "child", @@ -34728,7 +43164,21 @@ "name": "type", "wireName": "type", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_FREEMSG_PERCENTAGE", + "module": "WASmaxInSmbMeteredMessagingAccountEnums", + "variants": [ + { + "name": "free_msg", + "value": "free_msg" + }, + { + "name": "percentage", + "value": "percentage" + } + ] + } }, { "method": "maybeAttrInt", @@ -34810,7 +43260,37 @@ "name": "value", "wireName": "value", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_ALREADYCLAIMED_EXPIRED_INVALID_NOTFOUND_NOTOWNED_VALID", + "module": "WASmaxInSmbMeteredMessagingAccountEnums", + "variants": [ + { + "name": "already_claimed", + "value": "already_claimed" + }, + { + "name": "expired", + "value": "expired" + }, + { + "name": "invalid", + "value": "invalid" + }, + { + "name": "not_found", + "value": "not_found" + }, + { + "name": "not_owned", + "value": "not_owned" + }, + { + "name": "valid", + "value": "valid" + } + ] + } } ], "repeats": false @@ -34821,11 +43301,62 @@ "tag": "GetSMBMeteredMessagingCheckoutResponseError", "moduleName": "WASmaxInSmbMeteredMessagingAccountGetSMBMeteredMessagingCheckoutResponseError", "kind": "error", + "errorArms": [ + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorNotAuthorized", + "code": 401, + "text": "not-authorized" + }, + { + "name": "IQErrorNotAllowed", + "code": 405, + "text": "not-allowed" + }, + { + "name": "IQErrorRateOverlimit", + "code": 429, + "text": "rate-overlimit" + }, + { + "name": "IQErrorFeatureLimit", + "code": 482, + "text": "feature-limit" + }, + { + "name": "IQErrorServiceUnavailable", + "code": 503, + "text": "service-unavailable" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -34845,7 +43376,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -34861,14 +43393,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -34880,6 +43414,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -34891,14 +43430,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -34910,6 +43451,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -34921,14 +43467,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-authorized" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "401" } ], "assertions": [ @@ -34940,6 +43488,11 @@ "kind": "attr", "name": "text", "value": "not-authorized" + }, + { + "kind": "attr", + "name": "code", + "value": "401" } ] }, @@ -34951,14 +43504,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-allowed" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "405" } ], "assertions": [ @@ -34970,6 +43525,11 @@ "kind": "attr", "name": "text", "value": "not-allowed" + }, + { + "kind": "attr", + "name": "code", + "value": "405" } ] }, @@ -34981,14 +43541,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "rate-overlimit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "429" } ], "assertions": [ @@ -35000,6 +43562,11 @@ "kind": "attr", "name": "text", "value": "rate-overlimit" + }, + { + "kind": "attr", + "name": "code", + "value": "429" } ] }, @@ -35011,14 +43578,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "feature-limit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "482" } ], "assertions": [ @@ -35030,6 +43599,11 @@ "kind": "attr", "name": "text", "value": "feature-limit" + }, + { + "kind": "attr", + "name": "code", + "value": "482" } ] }, @@ -35041,14 +43615,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "assertions": [ @@ -35060,6 +43636,11 @@ "kind": "attr", "name": "text", "value": "service-unavailable" + }, + { + "kind": "attr", + "name": "code", + "value": "503" } ] } @@ -35113,6 +43694,24 @@ "wireName": "value", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_FALSE_NOTSET_TRUE", + "module": "WASmaxInBizSettingsEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "notset", + "value": "notset" + }, + { + "name": "true", + "value": "true" + } + ] + }, "sourcePath": [ "smb_data_sharing_with_meta_consent" ] @@ -35135,7 +43734,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ], "variants": [ @@ -35148,6 +43748,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -35168,6 +43782,24 @@ "wireName": "value", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_FALSE_NOTSET_TRUE", + "module": "WASmaxInBizSettingsEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "notset", + "value": "notset" + }, + { + "name": "true", + "value": "true" + } + ] + }, "sourcePath": [ "smb_data_sharing_with_meta_consent" ] @@ -35190,7 +43822,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ] }, @@ -35198,11 +43831,47 @@ "tag": "SetPrivacySettingResponseError", "moduleName": "WASmaxInBizSettingsSetPrivacySettingResponseError", "kind": "error", + "errorArms": [ + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorFeatureNotImplemented", + "code": 501, + "text": "feature-not-implemented" + }, + { + "name": "IQErrorServiceUnavailable", + "code": 503, + "text": "service-unavailable" + }, + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -35215,7 +43884,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -35231,14 +43901,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -35250,6 +43922,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -35261,14 +43938,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "feature-not-implemented" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "501" } ], "assertions": [ @@ -35280,6 +43959,11 @@ "kind": "attr", "name": "text", "value": "feature-not-implemented" + }, + { + "kind": "attr", + "name": "code", + "value": "501" } ] }, @@ -35291,14 +43975,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "assertions": [ @@ -35310,6 +43996,11 @@ "kind": "attr", "name": "text", "value": "service-unavailable" + }, + { + "kind": "attr", + "name": "code", + "value": "503" } ] }, @@ -35321,14 +44012,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -35340,6 +44033,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] } @@ -36034,7 +44732,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ], "variants": [ @@ -36047,6 +44746,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -36059,19 +44772,56 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ] }, { "tag": "UpdatePreferenceResponseInvalidRequest", "moduleName": "WASmaxInBizMsgUserFeedbackUpdatePreferenceResponseInvalidRequest", - "kind": "error", + "kind": "client_error", + "errorArms": [ + { + "name": "IQErrorNotAcceptable", + "code": 406, + "text": "not-acceptable" + }, + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorForbidden", + "code": 403, + "text": "forbidden" + }, + { + "name": "IQErrorRateOverlimit", + "code": 429, + "text": "rate-overlimit" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -36084,7 +44834,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -36100,14 +44851,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-acceptable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "406" }, { "method": "child", @@ -36143,6 +44896,11 @@ "kind": "attr", "name": "text", "value": "not-acceptable" + }, + { + "kind": "attr", + "name": "code", + "value": "406" } ] }, @@ -36154,14 +44912,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -36173,6 +44933,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -36184,14 +44949,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "forbidden" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "403" } ], "assertions": [ @@ -36203,6 +44970,11 @@ "kind": "attr", "name": "text", "value": "forbidden" + }, + { + "kind": "attr", + "name": "code", + "value": "403" } ] }, @@ -36214,14 +44986,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "rate-overlimit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "429" } ], "assertions": [ @@ -36233,6 +45007,11 @@ "kind": "attr", "name": "text", "value": "rate-overlimit" + }, + { + "kind": "attr", + "name": "code", + "value": "429" } ] } @@ -36246,12 +45025,38 @@ { "tag": "UpdatePreferenceResponseServerError", "moduleName": "WASmaxInBizMsgUserFeedbackUpdatePreferenceResponseServerError", - "kind": "error", + "kind": "server_error", + "errorArms": [ + { + "name": "IQErrorFeatureNotImplemented", + "code": 501, + "text": "feature-not-implemented" + }, + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -36264,7 +45069,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -36280,14 +45086,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "feature-not-implemented" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "501" } ], "assertions": [ @@ -36299,6 +45107,11 @@ "kind": "attr", "name": "text", "value": "feature-not-implemented" + }, + { + "kind": "attr", + "name": "code", + "value": "501" } ] }, @@ -36310,14 +45123,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -36329,6 +45144,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] } @@ -36395,7 +45215,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ], "variants": [ @@ -36408,6 +45229,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -36420,7 +45255,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ] }, @@ -36428,11 +45264,42 @@ "tag": "EventResponseError", "moduleName": "WASmaxInInAppCommsEventResponseError", "kind": "error", + "errorArms": [ + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorRequestTimeout", + "code": 408, + "text": "request-timeout" + }, + { + "name": "IQErrorServiceUnavailable", + "code": 503, + "text": "service-unavailable" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -36445,7 +45312,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -36461,14 +45329,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -36480,6 +45350,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -36491,14 +45366,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "request-timeout" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "408" } ], "assertions": [ @@ -36510,6 +45387,11 @@ "kind": "attr", "name": "text", "value": "request-timeout" + }, + { + "kind": "attr", + "name": "code", + "value": "408" } ] }, @@ -36521,14 +45403,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "assertions": [ @@ -36540,6 +45424,11 @@ "kind": "attr", "name": "text", "value": "service-unavailable" + }, + { + "kind": "attr", + "name": "code", + "value": "503" } ] } @@ -36593,6 +45482,20 @@ "wireName": "status", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_BLOCKED_UNBLOCKED", + "module": "WASmaxInPsaEnums", + "variants": [ + { + "name": "blocked", + "value": "blocked" + }, + { + "name": "unblocked", + "value": "unblocked" + } + ] + }, "sourcePath": [ "blocking" ] @@ -36602,7 +45505,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ], "variants": [ @@ -36615,6 +45519,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -36628,6 +45546,20 @@ "wireName": "status", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_BLOCKED_UNBLOCKED", + "module": "WASmaxInPsaEnums", + "variants": [ + { + "name": "blocked", + "value": "blocked" + }, + { + "name": "unblocked", + "value": "unblocked" + } + ] + }, "sourcePath": [ "blocking" ] @@ -36637,7 +45569,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ] }, @@ -36645,11 +45578,47 @@ "tag": "ChatBlockGetResponseServerError", "moduleName": "WASmaxInPsaChatBlockGetResponseServerError", "kind": "error", + "errorArms": [ + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorRequestTimeout", + "code": 408, + "text": "request-timeout" + }, + { + "name": "IQErrorServiceUnavailable", + "code": 503, + "text": "service-unavailable" + }, + { + "name": "IQErrorRateOverlimit", + "code": 429, + "text": "rate-overlimit" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -36662,7 +45631,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -36678,14 +45648,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -36697,6 +45669,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -36708,14 +45685,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "request-timeout" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "408" } ], "assertions": [ @@ -36727,6 +45706,11 @@ "kind": "attr", "name": "text", "value": "request-timeout" + }, + { + "kind": "attr", + "name": "code", + "value": "408" } ] }, @@ -36738,14 +45722,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "assertions": [ @@ -36757,6 +45743,11 @@ "kind": "attr", "name": "text", "value": "service-unavailable" + }, + { + "kind": "attr", + "name": "code", + "value": "503" } ] }, @@ -36768,14 +45759,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "rate-overlimit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "429" } ], "assertions": [ @@ -36787,6 +45780,11 @@ "kind": "attr", "name": "text", "value": "rate-overlimit" + }, + { + "kind": "attr", + "name": "code", + "value": "429" } ] } @@ -36839,6 +45837,20 @@ "wireName": "status", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_BLOCKED_UNBLOCKED", + "module": "WASmaxInPsaEnums", + "variants": [ + { + "name": "blocked", + "value": "blocked" + }, + { + "name": "unblocked", + "value": "unblocked" + } + ] + }, "sourcePath": [ "blocking" ] @@ -36848,7 +45860,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ], "variants": [ @@ -36861,6 +45874,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -36874,6 +45901,20 @@ "wireName": "status", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_BLOCKED_UNBLOCKED", + "module": "WASmaxInPsaEnums", + "variants": [ + { + "name": "blocked", + "value": "blocked" + }, + { + "name": "unblocked", + "value": "unblocked" + } + ] + }, "sourcePath": [ "blocking" ] @@ -36883,7 +45924,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ] }, @@ -36891,11 +45933,47 @@ "tag": "ChatBlockSetResponseServerError", "moduleName": "WASmaxInPsaChatBlockSetResponseServerError", "kind": "error", + "errorArms": [ + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorRequestTimeout", + "code": 408, + "text": "request-timeout" + }, + { + "name": "IQErrorServiceUnavailable", + "code": 503, + "text": "service-unavailable" + }, + { + "name": "IQErrorRateOverlimit", + "code": 429, + "text": "rate-overlimit" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -36908,7 +45986,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -36924,14 +46003,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -36943,6 +46024,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -36954,14 +46040,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "request-timeout" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "408" } ], "assertions": [ @@ -36973,6 +46061,11 @@ "kind": "attr", "name": "text", "value": "request-timeout" + }, + { + "kind": "attr", + "name": "code", + "value": "408" } ] }, @@ -36984,14 +46077,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "assertions": [ @@ -37003,6 +46098,11 @@ "kind": "attr", "name": "text", "value": "service-unavailable" + }, + { + "kind": "attr", + "name": "code", + "value": "503" } ] }, @@ -37014,14 +46114,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "rate-overlimit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "429" } ], "assertions": [ @@ -37033,6 +46135,11 @@ "kind": "attr", "name": "text", "value": "rate-overlimit" + }, + { + "kind": "attr", + "name": "code", + "value": "429" } ] } @@ -37098,7 +46205,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "child", @@ -37125,7 +46233,25 @@ "name": "createCtx", "wireName": "create_ctx", "type": "enum", - "required": false + "required": false, + "enumRef": { + "name": "ENUM_E2EEMIGRATION_REGULAR_RTC", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "e2ee_migration", + "value": "e2ee_migration" + }, + { + "name": "regular", + "value": "regular" + }, + { + "name": "rtc", + "value": "rtc" + } + ] + } } ], "sameNode": true @@ -37144,7 +46270,8 @@ "name": "ack", "wireName": "ack", "type": "string", - "required": false + "required": false, + "literalValue": "false" }, { "method": "attrString", @@ -37222,7 +46349,21 @@ "name": "addressingMode", "wireName": "addressing_mode", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_LID_PN", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "lid", + "value": "lid" + }, + { + "name": "pn", + "value": "pn" + } + ] + } } ], "sameNode": true @@ -37678,7 +46819,8 @@ "name": "defaultMembershipApprovalMode", "wireName": "default_membership_approval_mode", "type": "string", - "required": true + "required": true, + "literalValue": "request_required" } ], "sameNode": true @@ -37738,7 +46880,8 @@ "name": "canAutoFile", "wireName": "can_auto_file", "type": "string", - "required": false + "required": false, + "literalValue": "true" } ], "repeats": false @@ -37755,7 +46898,29 @@ "name": "type", "wireName": "type", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_APPROVED_INREVIEW_NONE_REJECTED", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "approved", + "value": "approved" + }, + { + "name": "in_review", + "value": "in_review" + }, + { + "name": "none", + "value": "none" + }, + { + "name": "rejected", + "value": "rejected" + } + ] + } } ], "repeats": false @@ -37789,7 +46954,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "invite" }, { "method": "attrInt", @@ -37826,6 +46992,7 @@ "wireName": "state", "type": "string", "required": true, + "literalValue": "on", "sourcePath": [ "group_join" ] @@ -37972,7 +47139,21 @@ "name": "type", "wireName": "type", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_ADMIN_SUPERADMIN", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "admin", + "value": "admin" + }, + { + "name": "superadmin", + "value": "superadmin" + } + ] + } }, { "method": "maybeAttrString", @@ -38000,7 +47181,21 @@ "name": "groupHistorySent", "wireName": "group_history_sent", "type": "enum", - "required": false + "required": false, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + } }, { "method": "", @@ -38292,7 +47487,21 @@ "name": "groupHistorySent", "wireName": "group_history_sent", "type": "enum", - "required": false + "required": false, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + } }, { "method": "", @@ -38568,7 +47777,8 @@ "name": "addressable", "wireName": "addressable", "type": "string", - "required": true + "required": true, + "literalValue": "false" } ], "sameNode": true @@ -38599,7 +47809,8 @@ "name": "truncated", "wireName": "truncated", "type": "string", - "required": true + "required": true, + "literalValue": "true" }, { "method": "attrInt", @@ -38638,7 +47849,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "403" } ], "assertions": [ @@ -38668,7 +47880,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "404" } ], "assertions": [ @@ -38702,10 +47915,24 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", "value": "result" + }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] } ], "fields": [ @@ -38714,7 +47941,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "child", @@ -38741,7 +47969,25 @@ "name": "createCtx", "wireName": "create_ctx", "type": "enum", - "required": false + "required": false, + "enumRef": { + "name": "ENUM_E2EEMIGRATION_REGULAR_RTC", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "e2ee_migration", + "value": "e2ee_migration" + }, + { + "name": "regular", + "value": "regular" + }, + { + "name": "rtc", + "value": "rtc" + } + ] + } } ], "sameNode": true @@ -38760,7 +48006,8 @@ "name": "ack", "wireName": "ack", "type": "string", - "required": false + "required": false, + "literalValue": "false" }, { "method": "attrString", @@ -38838,7 +48085,21 @@ "name": "addressingMode", "wireName": "addressing_mode", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_LID_PN", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "lid", + "value": "lid" + }, + { + "name": "pn", + "value": "pn" + } + ] + } } ], "sameNode": true @@ -39294,7 +48555,8 @@ "name": "defaultMembershipApprovalMode", "wireName": "default_membership_approval_mode", "type": "string", - "required": true + "required": true, + "literalValue": "request_required" } ], "sameNode": true @@ -39354,7 +48616,8 @@ "name": "canAutoFile", "wireName": "can_auto_file", "type": "string", - "required": false + "required": false, + "literalValue": "true" } ], "repeats": false @@ -39371,7 +48634,29 @@ "name": "type", "wireName": "type", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_APPROVED_INREVIEW_NONE_REJECTED", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "approved", + "value": "approved" + }, + { + "name": "in_review", + "value": "in_review" + }, + { + "name": "none", + "value": "none" + }, + { + "name": "rejected", + "value": "rejected" + } + ] + } } ], "repeats": false @@ -39405,7 +48690,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "invite" }, { "method": "attrInt", @@ -39442,6 +48728,7 @@ "wireName": "state", "type": "string", "required": true, + "literalValue": "on", "sourcePath": [ "group_join" ] @@ -39588,7 +48875,21 @@ "name": "type", "wireName": "type", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_ADMIN_SUPERADMIN", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "admin", + "value": "admin" + }, + { + "name": "superadmin", + "value": "superadmin" + } + ] + } }, { "method": "maybeAttrString", @@ -39616,7 +48917,21 @@ "name": "groupHistorySent", "wireName": "group_history_sent", "type": "enum", - "required": false + "required": false, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + } }, { "method": "", @@ -39908,7 +49223,21 @@ "name": "groupHistorySent", "wireName": "group_history_sent", "type": "enum", - "required": false + "required": false, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + } }, { "method": "", @@ -40184,7 +49513,8 @@ "name": "addressable", "wireName": "addressable", "type": "string", - "required": true + "required": true, + "literalValue": "false" } ], "sameNode": true @@ -40215,7 +49545,8 @@ "name": "truncated", "wireName": "truncated", "type": "string", - "required": true + "required": true, + "literalValue": "true" }, { "method": "attrInt", @@ -40254,7 +49585,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "403" } ], "assertions": [ @@ -40284,7 +49616,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "404" } ], "assertions": [ @@ -40312,12 +49645,38 @@ { "tag": "BatchGetGroupInfoResponseClientError", "moduleName": "WASmaxInGroupsBatchGetGroupInfoResponseClientError", - "kind": "error", + "kind": "client_error", + "errorArms": [ + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorRateOverlimit", + "code": 429, + "text": "rate-overlimit" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -40330,7 +49689,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -40346,14 +49706,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -40365,6 +49727,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -40376,14 +49743,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "rate-overlimit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "429" } ], "assertions": [ @@ -40395,6 +49764,11 @@ "kind": "attr", "name": "text", "value": "rate-overlimit" + }, + { + "kind": "attr", + "name": "code", + "value": "429" } ] } @@ -40408,12 +49782,48 @@ { "tag": "BatchGetGroupInfoResponseServerError", "moduleName": "WASmaxInGroupsBatchGetGroupInfoResponseServerError", - "kind": "error", + "kind": "server_error", + "errorArms": [ + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorServiceUnavailable", + "code": 503, + "text": "service-unavailable" + }, + { + "name": "IQErrorPartialServerError", + "code": 530, + "text": "partial-server-error" + }, + { + "name": "IQErrorFallbackServer", + "codeMin": 500, + "codeMax": 599 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -40426,7 +49836,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -40442,14 +49853,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -40461,6 +49874,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -40472,14 +49890,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "assertions": [ @@ -40491,6 +49911,11 @@ "kind": "attr", "name": "text", "value": "service-unavailable" + }, + { + "kind": "attr", + "name": "code", + "value": "503" } ] }, @@ -40502,14 +49927,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "partial-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "530" } ], "assertions": [ @@ -40521,6 +49948,11 @@ "kind": "attr", "name": "text", "value": "partial-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "530" } ] }, @@ -40613,7 +50045,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "child", @@ -40636,7 +50069,8 @@ "name": "ack", "wireName": "ack", "type": "string", - "required": false + "required": false, + "literalValue": "false" }, { "method": "attrString", @@ -40705,7 +50139,21 @@ "name": "addressingMode", "wireName": "addressing_mode", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_LID_PN", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "lid", + "value": "lid" + }, + { + "name": "pn", + "value": "pn" + } + ] + } } ], "sameNode": true @@ -41161,7 +50609,8 @@ "name": "defaultMembershipApprovalMode", "wireName": "default_membership_approval_mode", "type": "string", - "required": true + "required": true, + "literalValue": "request_required" } ], "sameNode": true @@ -41221,7 +50670,8 @@ "name": "canAutoFile", "wireName": "can_auto_file", "type": "string", - "required": false + "required": false, + "literalValue": "true" } ], "repeats": false @@ -41238,7 +50688,29 @@ "name": "type", "wireName": "type", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_APPROVED_INREVIEW_NONE_REJECTED", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "approved", + "value": "approved" + }, + { + "name": "in_review", + "value": "in_review" + }, + { + "name": "none", + "value": "none" + }, + { + "name": "rejected", + "value": "rejected" + } + ] + } } ], "repeats": false @@ -41272,7 +50744,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "invite" }, { "method": "attrInt", @@ -41309,6 +50782,7 @@ "wireName": "state", "type": "string", "required": true, + "literalValue": "on", "sourcePath": [ "group_join" ] @@ -41455,7 +50929,21 @@ "name": "type", "wireName": "type", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_ADMIN_SUPERADMIN", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "admin", + "value": "admin" + }, + { + "name": "superadmin", + "value": "superadmin" + } + ] + } }, { "method": "maybeAttrString", @@ -41483,7 +50971,21 @@ "name": "groupHistorySent", "wireName": "group_history_sent", "type": "enum", - "required": false + "required": false, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + } }, { "method": "", @@ -41775,7 +51277,21 @@ "name": "groupHistorySent", "wireName": "group_history_sent", "type": "enum", - "required": false + "required": false, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + } }, { "method": "", @@ -42051,7 +51567,8 @@ "name": "addressable", "wireName": "addressable", "type": "string", - "required": true + "required": true, + "literalValue": "false" } ], "sameNode": true @@ -42077,7 +51594,25 @@ "name": "createCtx", "wireName": "create_ctx", "type": "enum", - "required": false + "required": false, + "enumRef": { + "name": "ENUM_E2EEMIGRATION_REGULAR_RTC", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "e2ee_migration", + "value": "e2ee_migration" + }, + { + "name": "regular", + "value": "regular" + }, + { + "name": "rtc", + "value": "rtc" + } + ] + } } ], "sameNode": true @@ -42096,10 +51631,24 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", "value": "result" + }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] } ], "fields": [ @@ -42108,7 +51657,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "child", @@ -42131,7 +51681,8 @@ "name": "ack", "wireName": "ack", "type": "string", - "required": false + "required": false, + "literalValue": "false" }, { "method": "attrString", @@ -42200,7 +51751,21 @@ "name": "addressingMode", "wireName": "addressing_mode", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_LID_PN", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "lid", + "value": "lid" + }, + { + "name": "pn", + "value": "pn" + } + ] + } } ], "sameNode": true @@ -42656,7 +52221,8 @@ "name": "defaultMembershipApprovalMode", "wireName": "default_membership_approval_mode", "type": "string", - "required": true + "required": true, + "literalValue": "request_required" } ], "sameNode": true @@ -42716,7 +52282,8 @@ "name": "canAutoFile", "wireName": "can_auto_file", "type": "string", - "required": false + "required": false, + "literalValue": "true" } ], "repeats": false @@ -42733,7 +52300,29 @@ "name": "type", "wireName": "type", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_APPROVED_INREVIEW_NONE_REJECTED", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "approved", + "value": "approved" + }, + { + "name": "in_review", + "value": "in_review" + }, + { + "name": "none", + "value": "none" + }, + { + "name": "rejected", + "value": "rejected" + } + ] + } } ], "repeats": false @@ -42767,7 +52356,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "invite" }, { "method": "attrInt", @@ -42804,6 +52394,7 @@ "wireName": "state", "type": "string", "required": true, + "literalValue": "on", "sourcePath": [ "group_join" ] @@ -42950,7 +52541,21 @@ "name": "type", "wireName": "type", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_ADMIN_SUPERADMIN", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "admin", + "value": "admin" + }, + { + "name": "superadmin", + "value": "superadmin" + } + ] + } }, { "method": "maybeAttrString", @@ -42978,7 +52583,21 @@ "name": "groupHistorySent", "wireName": "group_history_sent", "type": "enum", - "required": false + "required": false, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + } }, { "method": "", @@ -43270,7 +52889,21 @@ "name": "groupHistorySent", "wireName": "group_history_sent", "type": "enum", - "required": false + "required": false, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + } }, { "method": "", @@ -43546,7 +53179,8 @@ "name": "addressable", "wireName": "addressable", "type": "string", - "required": true + "required": true, + "literalValue": "false" } ], "sameNode": true @@ -43572,7 +53206,25 @@ "name": "createCtx", "wireName": "create_ctx", "type": "enum", - "required": false + "required": false, + "enumRef": { + "name": "ENUM_E2EEMIGRATION_REGULAR_RTC", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "e2ee_migration", + "value": "e2ee_migration" + }, + { + "name": "regular", + "value": "regular" + }, + { + "name": "rtc", + "value": "rtc" + } + ] + } } ], "sameNode": true @@ -43585,12 +53237,58 @@ { "tag": "GetGroupInfoResponseClientError", "moduleName": "WASmaxInGroupsGetGroupInfoResponseClientError", - "kind": "error", + "kind": "client_error", + "errorArms": [ + { + "name": "IQErrorGone", + "code": 410, + "text": "gone" + }, + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorForbidden", + "code": 403, + "text": "forbidden" + }, + { + "name": "IQErrorItemNotFound", + "code": 404, + "text": "item-not-found" + }, + { + "name": "IQErrorRateOverlimit", + "code": 429, + "text": "rate-overlimit" + }, + { + "name": "IQErrorFallbackClient", + "codeMin": 400, + "codeMax": 499 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -43603,7 +53301,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -43619,14 +53318,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "gone" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "410" } ], "assertions": [ @@ -43638,6 +53339,11 @@ "kind": "attr", "name": "text", "value": "gone" + }, + { + "kind": "attr", + "name": "code", + "value": "410" } ] }, @@ -43649,14 +53355,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -43668,6 +53376,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -43679,14 +53392,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "forbidden" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "403" } ], "assertions": [ @@ -43698,6 +53413,11 @@ "kind": "attr", "name": "text", "value": "forbidden" + }, + { + "kind": "attr", + "name": "code", + "value": "403" } ] }, @@ -43709,14 +53429,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "item-not-found" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "404" } ], "assertions": [ @@ -43728,6 +53450,11 @@ "kind": "attr", "name": "text", "value": "item-not-found" + }, + { + "kind": "attr", + "name": "code", + "value": "404" } ] }, @@ -43739,14 +53466,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "rate-overlimit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "429" } ], "assertions": [ @@ -43758,6 +53487,11 @@ "kind": "attr", "name": "text", "value": "rate-overlimit" + }, + { + "kind": "attr", + "name": "code", + "value": "429" } ] }, @@ -43798,12 +53532,48 @@ { "tag": "GetGroupInfoResponseServerError", "moduleName": "WASmaxInGroupsGetGroupInfoResponseServerError", - "kind": "error", + "kind": "server_error", + "errorArms": [ + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorServiceUnavailable", + "code": 503, + "text": "service-unavailable" + }, + { + "name": "IQErrorPartialServerError", + "code": 530, + "text": "partial-server-error" + }, + { + "name": "IQErrorFallbackServer", + "codeMin": 500, + "codeMax": 599 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -43816,7 +53586,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -43832,14 +53603,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -43851,6 +53624,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -43862,14 +53640,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "assertions": [ @@ -43881,6 +53661,11 @@ "kind": "attr", "name": "text", "value": "service-unavailable" + }, + { + "kind": "attr", + "name": "code", + "value": "503" } ] }, @@ -43892,14 +53677,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "partial-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "530" } ], "assertions": [ @@ -43911,6 +53698,11 @@ "kind": "attr", "name": "text", "value": "partial-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "530" } ] }, @@ -43976,7 +53768,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "child", @@ -44038,7 +53831,21 @@ "name": "type", "wireName": "type", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_IMAGE_PREVIEW", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "image", + "value": "image" + }, + { + "name": "preview", + "value": "preview" + } + ] + } }, { "method": "", @@ -44115,7 +53922,8 @@ "name": "status", "wireName": "status", "type": "string", - "required": true + "required": true, + "literalValue": "304" } ], "assertions": [ @@ -44138,7 +53946,8 @@ "name": "status", "wireName": "status", "type": "string", - "required": true + "required": true, + "literalValue": "204" } ], "assertions": [ @@ -44161,7 +53970,8 @@ "name": "status", "wireName": "status", "type": "string", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -44184,7 +53994,8 @@ "name": "status", "wireName": "status", "type": "string", - "required": true + "required": true, + "literalValue": "405" } ], "assertions": [ @@ -44228,6 +54039,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -44240,7 +54065,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "child", @@ -44302,7 +54128,21 @@ "name": "type", "wireName": "type", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_IMAGE_PREVIEW", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "image", + "value": "image" + }, + { + "name": "preview", + "value": "preview" + } + ] + } }, { "method": "", @@ -44379,7 +54219,8 @@ "name": "status", "wireName": "status", "type": "string", - "required": true + "required": true, + "literalValue": "304" } ], "assertions": [ @@ -44402,7 +54243,8 @@ "name": "status", "wireName": "status", "type": "string", - "required": true + "required": true, + "literalValue": "204" } ], "assertions": [ @@ -44425,7 +54267,8 @@ "name": "status", "wireName": "status", "type": "string", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -44448,7 +54291,8 @@ "name": "status", "wireName": "status", "type": "string", - "required": true + "required": true, + "literalValue": "405" } ], "assertions": [ @@ -44486,12 +54330,58 @@ { "tag": "GetGroupProfilePicturesResponseClientError", "moduleName": "WASmaxInGroupsGetGroupProfilePicturesResponseClientError", - "kind": "error", + "kind": "client_error", + "errorArms": [ + { + "name": "IQErrorItemNotFound", + "code": 404, + "text": "item-not-found" + }, + { + "name": "IQErrorForbidden", + "code": 403, + "text": "forbidden" + }, + { + "name": "IQErrorNotAllowed", + "code": 405, + "text": "not-allowed" + }, + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorRateOverlimit", + "code": 429, + "text": "rate-overlimit" + }, + { + "name": "IQErrorFallbackClient", + "codeMin": 400, + "codeMax": 499 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -44504,7 +54394,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -44520,14 +54411,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "item-not-found" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "404" } ], "assertions": [ @@ -44539,6 +54432,11 @@ "kind": "attr", "name": "text", "value": "item-not-found" + }, + { + "kind": "attr", + "name": "code", + "value": "404" } ] }, @@ -44550,14 +54448,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "forbidden" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "403" } ], "assertions": [ @@ -44569,6 +54469,11 @@ "kind": "attr", "name": "text", "value": "forbidden" + }, + { + "kind": "attr", + "name": "code", + "value": "403" } ] }, @@ -44580,14 +54485,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-allowed" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "405" } ], "assertions": [ @@ -44599,6 +54506,11 @@ "kind": "attr", "name": "text", "value": "not-allowed" + }, + { + "kind": "attr", + "name": "code", + "value": "405" } ] }, @@ -44610,14 +54522,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -44629,6 +54543,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -44640,14 +54559,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "rate-overlimit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "429" } ], "assertions": [ @@ -44659,6 +54580,11 @@ "kind": "attr", "name": "text", "value": "rate-overlimit" + }, + { + "kind": "attr", + "name": "code", + "value": "429" } ] }, @@ -44699,12 +54625,48 @@ { "tag": "GetGroupProfilePicturesResponseServerError", "moduleName": "WASmaxInGroupsGetGroupProfilePicturesResponseServerError", - "kind": "error", + "kind": "server_error", + "errorArms": [ + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorServiceUnavailable", + "code": 503, + "text": "service-unavailable" + }, + { + "name": "IQErrorPartialServerError", + "code": 530, + "text": "partial-server-error" + }, + { + "name": "IQErrorFallbackServer", + "codeMin": 500, + "codeMax": 599 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -44717,7 +54679,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -44733,14 +54696,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -44752,6 +54717,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -44763,14 +54733,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "assertions": [ @@ -44782,6 +54754,11 @@ "kind": "attr", "name": "text", "value": "service-unavailable" + }, + { + "kind": "attr", + "name": "code", + "value": "503" } ] }, @@ -44793,14 +54770,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "partial-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "530" } ], "assertions": [ @@ -44812,6 +54791,11 @@ "kind": "attr", "name": "text", "value": "partial-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "530" } ] }, @@ -44890,7 +54874,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "attrInt", @@ -45068,7 +55053,21 @@ "name": "addressingMode", "wireName": "addressing_mode", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_LID_PN", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "lid", + "value": "lid" + }, + { + "name": "pn", + "value": "pn" + } + ] + } } ], "sameNode": true @@ -45283,6 +55282,7 @@ "wireName": "state", "type": "string", "required": true, + "literalValue": "on", "sourcePath": [ "group_join" ] @@ -45302,7 +55302,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": false + "required": false, + "literalValue": "304" } ], "repeats": false @@ -45368,7 +55369,21 @@ "name": "type", "wireName": "type", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_ADMIN_SUPERADMIN", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "admin", + "value": "admin" + }, + { + "name": "superadmin", + "value": "superadmin" + } + ] + } }, { "method": "maybeAttrString", @@ -45396,7 +55411,21 @@ "name": "groupHistorySent", "wireName": "group_history_sent", "type": "enum", - "required": false + "required": false, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + } }, { "method": "", @@ -45688,7 +55717,21 @@ "name": "groupHistorySent", "wireName": "group_history_sent", "type": "enum", - "required": false + "required": false, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + } }, { "method": "", @@ -45970,10 +56013,24 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", "value": "result" + }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] } ], "fields": [ @@ -45982,7 +56039,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "attrInt", @@ -46160,7 +56218,21 @@ "name": "addressingMode", "wireName": "addressing_mode", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_LID_PN", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "lid", + "value": "lid" + }, + { + "name": "pn", + "value": "pn" + } + ] + } } ], "sameNode": true @@ -46375,6 +56447,7 @@ "wireName": "state", "type": "string", "required": true, + "literalValue": "on", "sourcePath": [ "group_join" ] @@ -46394,7 +56467,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": false + "required": false, + "literalValue": "304" } ], "repeats": false @@ -46460,7 +56534,21 @@ "name": "type", "wireName": "type", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_ADMIN_SUPERADMIN", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "admin", + "value": "admin" + }, + { + "name": "superadmin", + "value": "superadmin" + } + ] + } }, { "method": "maybeAttrString", @@ -46488,7 +56576,21 @@ "name": "groupHistorySent", "wireName": "group_history_sent", "type": "enum", - "required": false + "required": false, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + } }, { "method": "", @@ -46780,7 +56882,21 @@ "name": "groupHistorySent", "wireName": "group_history_sent", "type": "enum", - "required": false + "required": false, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + } }, { "method": "", @@ -47056,12 +57172,73 @@ { "tag": "GetInviteGroupInfoResponseClientError", "moduleName": "WASmaxInGroupsGetInviteGroupInfoResponseClientError", - "kind": "error", + "kind": "client_error", + "errorArms": [ + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorItemNotFound", + "code": 404, + "text": "item-not-found" + }, + { + "name": "IQErrorGone", + "code": 410, + "text": "gone" + }, + { + "name": "IQErrorNotAuthorized", + "code": 401, + "text": "not-authorized" + }, + { + "name": "IQErrorNotAcceptable", + "code": 406, + "text": "not-acceptable" + }, + { + "name": "IQErrorLocked", + "code": 423, + "text": "locked" + }, + { + "name": "IQErrorGrowthLocked", + "code": 436, + "text": "growth-locked" + }, + { + "name": "IQErrorParentGroupSuspended", + "code": 416, + "text": "parent-group-suspended" + }, + { + "name": "IQErrorFallbackClient", + "codeMin": 400, + "codeMax": 499 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -47074,7 +57251,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -47090,14 +57268,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -47109,6 +57289,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -47120,14 +57305,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "item-not-found" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "404" } ], "assertions": [ @@ -47139,6 +57326,11 @@ "kind": "attr", "name": "text", "value": "item-not-found" + }, + { + "kind": "attr", + "name": "code", + "value": "404" } ] }, @@ -47150,14 +57342,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "gone" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "410" } ], "assertions": [ @@ -47169,6 +57363,11 @@ "kind": "attr", "name": "text", "value": "gone" + }, + { + "kind": "attr", + "name": "code", + "value": "410" } ] }, @@ -47180,14 +57379,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-authorized" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "401" } ], "assertions": [ @@ -47199,6 +57400,11 @@ "kind": "attr", "name": "text", "value": "not-authorized" + }, + { + "kind": "attr", + "name": "code", + "value": "401" } ] }, @@ -47210,14 +57416,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-acceptable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "406" }, { "method": "child", @@ -47253,6 +57461,11 @@ "kind": "attr", "name": "text", "value": "not-acceptable" + }, + { + "kind": "attr", + "name": "code", + "value": "406" } ] }, @@ -47264,14 +57477,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "locked" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "423" } ], "assertions": [ @@ -47283,6 +57498,11 @@ "kind": "attr", "name": "text", "value": "locked" + }, + { + "kind": "attr", + "name": "code", + "value": "423" } ] }, @@ -47294,14 +57514,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "growth-locked" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "436" }, { "method": "child", @@ -47315,7 +57537,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "invite" }, { "method": "attrInt", @@ -47337,6 +57560,11 @@ "kind": "attr", "name": "text", "value": "growth-locked" + }, + { + "kind": "attr", + "name": "code", + "value": "436" } ] }, @@ -47348,14 +57576,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "parent-group-suspended" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "416" } ], "assertions": [ @@ -47367,6 +57597,11 @@ "kind": "attr", "name": "text", "value": "parent-group-suspended" + }, + { + "kind": "attr", + "name": "code", + "value": "416" } ] }, @@ -47407,12 +57642,48 @@ { "tag": "GetInviteGroupInfoResponseServerError", "moduleName": "WASmaxInGroupsGetInviteGroupInfoResponseServerError", - "kind": "error", + "kind": "server_error", + "errorArms": [ + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorServiceUnavailable", + "code": 503, + "text": "service-unavailable" + }, + { + "name": "IQErrorPartialServerError", + "code": 530, + "text": "partial-server-error" + }, + { + "name": "IQErrorFallbackServer", + "codeMin": 500, + "codeMax": 599 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -47425,7 +57696,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -47441,14 +57713,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -47460,6 +57734,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -47471,14 +57750,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "assertions": [ @@ -47490,6 +57771,11 @@ "kind": "attr", "name": "text", "value": "service-unavailable" + }, + { + "kind": "attr", + "name": "code", + "value": "503" } ] }, @@ -47501,14 +57787,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "partial-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "530" } ], "assertions": [ @@ -47520,6 +57808,11 @@ "kind": "attr", "name": "text", "value": "partial-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "530" } ] }, @@ -47773,7 +58066,21 @@ "name": "addressingMode", "wireName": "addressing_mode", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_LID_PN", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "lid", + "value": "lid" + }, + { + "name": "pn", + "value": "pn" + } + ] + } } ], "sameNode": true @@ -47929,7 +58236,21 @@ "name": "addressingMode", "wireName": "addressing_mode", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_LID_PN", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "lid", + "value": "lid" + }, + { + "name": "pn", + "value": "pn" + } + ] + } } ], "repeats": false @@ -47947,6 +58268,7 @@ "wireName": "state", "type": "string", "required": true, + "literalValue": "on", "sourcePath": [ "group_join" ] @@ -47969,7 +58291,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": false + "required": false, + "literalValue": "304" } ], "repeats": false, @@ -48001,7 +58324,8 @@ "name": "canAutoFile", "wireName": "can_auto_file", "type": "string", - "required": false + "required": false, + "literalValue": "true" } ], "repeats": false, @@ -48021,7 +58345,29 @@ "name": "type", "wireName": "type", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_APPROVED_INREVIEW_NONE_REJECTED", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "approved", + "value": "approved" + }, + { + "name": "in_review", + "value": "in_review" + }, + { + "name": "none", + "value": "none" + }, + { + "name": "rejected", + "value": "rejected" + } + ] + } } ], "repeats": false, @@ -48104,7 +58450,21 @@ "name": "type", "wireName": "type", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_ADMIN_SUPERADMIN", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "admin", + "value": "admin" + }, + { + "name": "superadmin", + "value": "superadmin" + } + ] + } }, { "method": "maybeAttrString", @@ -48132,7 +58492,21 @@ "name": "groupHistorySent", "wireName": "group_history_sent", "type": "enum", - "required": false + "required": false, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + } }, { "method": "", @@ -48424,7 +58798,21 @@ "name": "groupHistorySent", "wireName": "group_history_sent", "type": "enum", - "required": false + "required": false, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + } }, { "method": "", @@ -48703,7 +59091,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "", @@ -48716,7 +59105,21 @@ "name": "addressingMode", "wireName": "addressing_mode", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_LID_PN", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "lid", + "value": "lid" + }, + { + "name": "pn", + "value": "pn" + } + ] + } } ], "sameNode": true @@ -48732,6 +59135,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -48932,7 +59349,21 @@ "name": "addressingMode", "wireName": "addressing_mode", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_LID_PN", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "lid", + "value": "lid" + }, + { + "name": "pn", + "value": "pn" + } + ] + } } ], "sameNode": true @@ -49088,7 +59519,21 @@ "name": "addressingMode", "wireName": "addressing_mode", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_LID_PN", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "lid", + "value": "lid" + }, + { + "name": "pn", + "value": "pn" + } + ] + } } ], "repeats": false @@ -49106,6 +59551,7 @@ "wireName": "state", "type": "string", "required": true, + "literalValue": "on", "sourcePath": [ "group_join" ] @@ -49128,7 +59574,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": false + "required": false, + "literalValue": "304" } ], "repeats": false, @@ -49160,7 +59607,8 @@ "name": "canAutoFile", "wireName": "can_auto_file", "type": "string", - "required": false + "required": false, + "literalValue": "true" } ], "repeats": false, @@ -49180,7 +59628,29 @@ "name": "type", "wireName": "type", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_APPROVED_INREVIEW_NONE_REJECTED", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "approved", + "value": "approved" + }, + { + "name": "in_review", + "value": "in_review" + }, + { + "name": "none", + "value": "none" + }, + { + "name": "rejected", + "value": "rejected" + } + ] + } } ], "repeats": false, @@ -49263,7 +59733,21 @@ "name": "type", "wireName": "type", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_ADMIN_SUPERADMIN", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "admin", + "value": "admin" + }, + { + "name": "superadmin", + "value": "superadmin" + } + ] + } }, { "method": "maybeAttrString", @@ -49291,7 +59775,21 @@ "name": "groupHistorySent", "wireName": "group_history_sent", "type": "enum", - "required": false + "required": false, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + } }, { "method": "", @@ -49583,7 +60081,21 @@ "name": "groupHistorySent", "wireName": "group_history_sent", "type": "enum", - "required": false + "required": false, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + } }, { "method": "", @@ -49862,7 +60374,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "", @@ -49875,7 +60388,21 @@ "name": "addressingMode", "wireName": "addressing_mode", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_LID_PN", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "lid", + "value": "lid" + }, + { + "name": "pn", + "value": "pn" + } + ] + } } ], "sameNode": true @@ -49885,12 +60412,53 @@ { "tag": "GetLinkedGroupResponseClientError", "moduleName": "WASmaxInGroupsGetLinkedGroupResponseClientError", - "kind": "error", + "kind": "client_error", + "errorArms": [ + { + "name": "IQErrorItemNotFound", + "code": 404, + "text": "item-not-found" + }, + { + "name": "IQErrorForbidden", + "code": 403, + "text": "forbidden" + }, + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorNotAllowed", + "code": 405, + "text": "not-allowed" + }, + { + "name": "IQErrorFallbackClient", + "codeMin": 400, + "codeMax": 499 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -49903,7 +60471,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -49919,14 +60488,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "item-not-found" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "404" } ], "assertions": [ @@ -49938,6 +60509,11 @@ "kind": "attr", "name": "text", "value": "item-not-found" + }, + { + "kind": "attr", + "name": "code", + "value": "404" } ] }, @@ -49949,14 +60525,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "forbidden" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "403" } ], "assertions": [ @@ -49968,6 +60546,11 @@ "kind": "attr", "name": "text", "value": "forbidden" + }, + { + "kind": "attr", + "name": "code", + "value": "403" } ] }, @@ -49979,14 +60562,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -49998,6 +60583,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -50009,14 +60599,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-allowed" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "405" } ], "assertions": [ @@ -50028,6 +60620,11 @@ "kind": "attr", "name": "text", "value": "not-allowed" + }, + { + "kind": "attr", + "name": "code", + "value": "405" } ] }, @@ -50068,12 +60665,48 @@ { "tag": "GetLinkedGroupResponseServerError", "moduleName": "WASmaxInGroupsGetLinkedGroupResponseServerError", - "kind": "error", + "kind": "server_error", + "errorArms": [ + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorServiceUnavailable", + "code": 503, + "text": "service-unavailable" + }, + { + "name": "IQErrorPartialServerError", + "code": 530, + "text": "partial-server-error" + }, + { + "name": "IQErrorFallbackServer", + "codeMin": 500, + "codeMax": 599 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -50086,7 +60719,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -50102,14 +60736,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -50121,6 +60757,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -50132,14 +60773,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "assertions": [ @@ -50151,6 +60794,11 @@ "kind": "attr", "name": "text", "value": "service-unavailable" + }, + { + "kind": "attr", + "name": "code", + "value": "503" } ] }, @@ -50162,14 +60810,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "partial-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "530" } ], "assertions": [ @@ -50181,6 +60831,11 @@ "kind": "attr", "name": "text", "value": "partial-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "530" } ] }, @@ -50253,7 +60908,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "", @@ -50266,7 +60922,21 @@ "name": "addressingMode", "wireName": "addressing_mode", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_LID_PN", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "lid", + "value": "lid" + }, + { + "name": "pn", + "value": "pn" + } + ] + } } ], "sameNode": true @@ -50318,6 +60988,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -50330,7 +61014,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "", @@ -50343,7 +61028,21 @@ "name": "addressingMode", "wireName": "addressing_mode", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_LID_PN", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "lid", + "value": "lid" + }, + { + "name": "pn", + "value": "pn" + } + ] + } } ], "sameNode": true @@ -50389,12 +61088,48 @@ { "tag": "GetLinkedGroupsParticipantsResponseClientError", "moduleName": "WASmaxInGroupsGetLinkedGroupsParticipantsResponseClientError", - "kind": "error", + "kind": "client_error", + "errorArms": [ + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorItemNotFound", + "code": 404, + "text": "item-not-found" + }, + { + "name": "IQErrorNotAuthorized", + "code": 401, + "text": "not-authorized" + }, + { + "name": "IQErrorRateOverlimit", + "code": 429, + "text": "rate-overlimit" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -50407,7 +61142,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -50423,14 +61159,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -50442,6 +61180,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -50453,14 +61196,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "item-not-found" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "404" } ], "assertions": [ @@ -50472,6 +61217,11 @@ "kind": "attr", "name": "text", "value": "item-not-found" + }, + { + "kind": "attr", + "name": "code", + "value": "404" } ] }, @@ -50483,14 +61233,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-authorized" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "401" } ], "assertions": [ @@ -50502,6 +61254,11 @@ "kind": "attr", "name": "text", "value": "not-authorized" + }, + { + "kind": "attr", + "name": "code", + "value": "401" } ] }, @@ -50513,14 +61270,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "rate-overlimit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "429" } ], "assertions": [ @@ -50532,6 +61291,11 @@ "kind": "attr", "name": "text", "value": "rate-overlimit" + }, + { + "kind": "attr", + "name": "code", + "value": "429" } ] } @@ -50545,12 +61309,48 @@ { "tag": "GetLinkedGroupsParticipantsResponseServerError", "moduleName": "WASmaxInGroupsGetLinkedGroupsParticipantsResponseServerError", - "kind": "error", + "kind": "server_error", + "errorArms": [ + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorServiceUnavailable", + "code": 503, + "text": "service-unavailable" + }, + { + "name": "IQErrorPartialServerError", + "code": 530, + "text": "partial-server-error" + }, + { + "name": "IQErrorFallbackServer", + "codeMin": 500, + "codeMax": 599 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -50563,7 +61363,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -50579,14 +61380,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -50598,6 +61401,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -50609,14 +61417,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "assertions": [ @@ -50628,6 +61438,11 @@ "kind": "attr", "name": "text", "value": "service-unavailable" + }, + { + "kind": "attr", + "name": "code", + "value": "503" } ] }, @@ -50639,14 +61454,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "partial-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "530" } ], "assertions": [ @@ -50658,6 +61475,11 @@ "kind": "attr", "name": "text", "value": "partial-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "530" } ] }, @@ -50737,7 +61559,8 @@ "name": "requestorFetch", "wireName": "requestor_fetch", "type": "string", - "required": true + "required": true, + "literalValue": "true" } ], "repeats": false @@ -50747,7 +61570,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "", @@ -50760,7 +61584,21 @@ "name": "addressingMode", "wireName": "addressing_mode", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_LID_PN", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "lid", + "value": "lid" + }, + { + "name": "pn", + "value": "pn" + } + ] + } } ], "sameNode": true @@ -50819,7 +61657,25 @@ "name": "requestMethod", "wireName": "request_method", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_INVITELINK_LINKEDGROUPJOIN_NONADMINADD", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "invite_link", + "value": "invite_link" + }, + { + "name": "linked_group_join", + "value": "linked_group_join" + }, + { + "name": "non_admin_add", + "value": "non_admin_add" + } + ] + } }, { "method": "", @@ -50898,6 +61754,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -50917,7 +61787,8 @@ "name": "requestorFetch", "wireName": "requestor_fetch", "type": "string", - "required": true + "required": true, + "literalValue": "true" } ], "repeats": false @@ -50927,7 +61798,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "", @@ -50940,7 +61812,21 @@ "name": "addressingMode", "wireName": "addressing_mode", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_LID_PN", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "lid", + "value": "lid" + }, + { + "name": "pn", + "value": "pn" + } + ] + } } ], "sameNode": true @@ -50999,7 +61885,25 @@ "name": "requestMethod", "wireName": "request_method", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_INVITELINK_LINKEDGROUPJOIN_NONADMINADD", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "invite_link", + "value": "invite_link" + }, + { + "name": "linked_group_join", + "value": "linked_group_join" + }, + { + "name": "non_admin_add", + "value": "non_admin_add" + } + ] + } }, { "method": "", @@ -51072,12 +61976,63 @@ { "tag": "GetMembershipApprovalRequestsResponseClientError", "moduleName": "WASmaxInGroupsGetMembershipApprovalRequestsResponseClientError", - "kind": "error", + "kind": "client_error", + "errorArms": [ + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorItemNotFound", + "code": 404, + "text": "item-not-found" + }, + { + "name": "IQErrorNotAuthorized", + "code": 401, + "text": "not-authorized" + }, + { + "name": "IQErrorForbidden", + "code": 403, + "text": "forbidden" + }, + { + "name": "IQErrorRateOverlimit", + "code": 429, + "text": "rate-overlimit" + }, + { + "name": "IQErrorLocked", + "code": 423, + "text": "locked" + }, + { + "name": "IQErrorFallbackClient", + "codeMin": 400, + "codeMax": 499 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -51090,7 +62045,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -51106,14 +62062,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -51125,6 +62083,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -51136,14 +62099,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "item-not-found" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "404" } ], "assertions": [ @@ -51155,6 +62120,11 @@ "kind": "attr", "name": "text", "value": "item-not-found" + }, + { + "kind": "attr", + "name": "code", + "value": "404" } ] }, @@ -51166,14 +62136,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-authorized" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "401" } ], "assertions": [ @@ -51185,6 +62157,11 @@ "kind": "attr", "name": "text", "value": "not-authorized" + }, + { + "kind": "attr", + "name": "code", + "value": "401" } ] }, @@ -51196,14 +62173,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "forbidden" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "403" } ], "assertions": [ @@ -51215,6 +62194,11 @@ "kind": "attr", "name": "text", "value": "forbidden" + }, + { + "kind": "attr", + "name": "code", + "value": "403" } ] }, @@ -51226,14 +62210,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "rate-overlimit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "429" } ], "assertions": [ @@ -51245,6 +62231,11 @@ "kind": "attr", "name": "text", "value": "rate-overlimit" + }, + { + "kind": "attr", + "name": "code", + "value": "429" } ] }, @@ -51256,14 +62247,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "locked" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "423" } ], "assertions": [ @@ -51275,6 +62268,11 @@ "kind": "attr", "name": "text", "value": "locked" + }, + { + "kind": "attr", + "name": "code", + "value": "423" } ] }, @@ -51315,12 +62313,48 @@ { "tag": "GetMembershipApprovalRequestsResponseServerError", "moduleName": "WASmaxInGroupsGetMembershipApprovalRequestsResponseServerError", - "kind": "error", + "kind": "server_error", + "errorArms": [ + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorServiceUnavailable", + "code": 503, + "text": "service-unavailable" + }, + { + "name": "IQErrorPartialServerError", + "code": 530, + "text": "partial-server-error" + }, + { + "name": "IQErrorFallbackServer", + "codeMin": 500, + "codeMax": 599 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -51333,7 +62367,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -51349,14 +62384,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -51368,6 +62405,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -51379,14 +62421,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "assertions": [ @@ -51398,6 +62442,11 @@ "kind": "attr", "name": "text", "value": "service-unavailable" + }, + { + "kind": "attr", + "name": "code", + "value": "503" } ] }, @@ -51409,14 +62458,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "partial-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "530" } ], "assertions": [ @@ -51428,6 +62479,11 @@ "kind": "attr", "name": "text", "value": "partial-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "530" } ] }, @@ -51515,7 +62571,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "child", @@ -51542,7 +62599,25 @@ "name": "createCtx", "wireName": "create_ctx", "type": "enum", - "required": false + "required": false, + "enumRef": { + "name": "ENUM_E2EEMIGRATION_REGULAR_RTC", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "e2ee_migration", + "value": "e2ee_migration" + }, + { + "name": "regular", + "value": "regular" + }, + { + "name": "rtc", + "value": "rtc" + } + ] + } } ], "sameNode": true @@ -51561,7 +62636,8 @@ "name": "ack", "wireName": "ack", "type": "string", - "required": false + "required": false, + "literalValue": "false" }, { "method": "attrString", @@ -51639,7 +62715,21 @@ "name": "addressingMode", "wireName": "addressing_mode", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_LID_PN", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "lid", + "value": "lid" + }, + { + "name": "pn", + "value": "pn" + } + ] + } } ], "sameNode": true @@ -52095,7 +63185,8 @@ "name": "defaultMembershipApprovalMode", "wireName": "default_membership_approval_mode", "type": "string", - "required": true + "required": true, + "literalValue": "request_required" } ], "sameNode": true @@ -52155,7 +63246,8 @@ "name": "canAutoFile", "wireName": "can_auto_file", "type": "string", - "required": false + "required": false, + "literalValue": "true" } ], "repeats": false @@ -52172,7 +63264,29 @@ "name": "type", "wireName": "type", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_APPROVED_INREVIEW_NONE_REJECTED", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "approved", + "value": "approved" + }, + { + "name": "in_review", + "value": "in_review" + }, + { + "name": "none", + "value": "none" + }, + { + "name": "rejected", + "value": "rejected" + } + ] + } } ], "repeats": false @@ -52206,7 +63320,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "invite" }, { "method": "attrInt", @@ -52243,6 +63358,7 @@ "wireName": "state", "type": "string", "required": true, + "literalValue": "on", "sourcePath": [ "group_join" ] @@ -52389,7 +63505,21 @@ "name": "type", "wireName": "type", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_ADMIN_SUPERADMIN", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "admin", + "value": "admin" + }, + { + "name": "superadmin", + "value": "superadmin" + } + ] + } }, { "method": "maybeAttrString", @@ -52417,7 +63547,21 @@ "name": "groupHistorySent", "wireName": "group_history_sent", "type": "enum", - "required": false + "required": false, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + } }, { "method": "", @@ -52709,7 +63853,21 @@ "name": "groupHistorySent", "wireName": "group_history_sent", "type": "enum", - "required": false + "required": false, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + } }, { "method": "", @@ -52985,7 +64143,8 @@ "name": "addressable", "wireName": "addressable", "type": "string", - "required": true + "required": true, + "literalValue": "false" } ], "sameNode": true @@ -53016,7 +64175,8 @@ "name": "truncated", "wireName": "truncated", "type": "string", - "required": true + "required": true, + "literalValue": "true" }, { "method": "attrInt", @@ -53059,10 +64219,24 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", "value": "result" + }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] } ], "fields": [ @@ -53071,7 +64245,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "child", @@ -53098,7 +64273,25 @@ "name": "createCtx", "wireName": "create_ctx", "type": "enum", - "required": false + "required": false, + "enumRef": { + "name": "ENUM_E2EEMIGRATION_REGULAR_RTC", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "e2ee_migration", + "value": "e2ee_migration" + }, + { + "name": "regular", + "value": "regular" + }, + { + "name": "rtc", + "value": "rtc" + } + ] + } } ], "sameNode": true @@ -53117,7 +64310,8 @@ "name": "ack", "wireName": "ack", "type": "string", - "required": false + "required": false, + "literalValue": "false" }, { "method": "attrString", @@ -53195,7 +64389,21 @@ "name": "addressingMode", "wireName": "addressing_mode", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_LID_PN", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "lid", + "value": "lid" + }, + { + "name": "pn", + "value": "pn" + } + ] + } } ], "sameNode": true @@ -53651,7 +64859,8 @@ "name": "defaultMembershipApprovalMode", "wireName": "default_membership_approval_mode", "type": "string", - "required": true + "required": true, + "literalValue": "request_required" } ], "sameNode": true @@ -53711,7 +64920,8 @@ "name": "canAutoFile", "wireName": "can_auto_file", "type": "string", - "required": false + "required": false, + "literalValue": "true" } ], "repeats": false @@ -53728,7 +64938,29 @@ "name": "type", "wireName": "type", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_APPROVED_INREVIEW_NONE_REJECTED", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "approved", + "value": "approved" + }, + { + "name": "in_review", + "value": "in_review" + }, + { + "name": "none", + "value": "none" + }, + { + "name": "rejected", + "value": "rejected" + } + ] + } } ], "repeats": false @@ -53762,7 +64994,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "invite" }, { "method": "attrInt", @@ -53799,6 +65032,7 @@ "wireName": "state", "type": "string", "required": true, + "literalValue": "on", "sourcePath": [ "group_join" ] @@ -53945,7 +65179,21 @@ "name": "type", "wireName": "type", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_ADMIN_SUPERADMIN", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "admin", + "value": "admin" + }, + { + "name": "superadmin", + "value": "superadmin" + } + ] + } }, { "method": "maybeAttrString", @@ -53973,7 +65221,21 @@ "name": "groupHistorySent", "wireName": "group_history_sent", "type": "enum", - "required": false + "required": false, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + } }, { "method": "", @@ -54265,7 +65527,21 @@ "name": "groupHistorySent", "wireName": "group_history_sent", "type": "enum", - "required": false + "required": false, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + } }, { "method": "", @@ -54541,7 +65817,8 @@ "name": "addressable", "wireName": "addressable", "type": "string", - "required": true + "required": true, + "literalValue": "false" } ], "sameNode": true @@ -54572,7 +65849,8 @@ "name": "truncated", "wireName": "truncated", "type": "string", - "required": true + "required": true, + "literalValue": "true" }, { "method": "attrInt", @@ -54609,12 +65887,43 @@ { "tag": "GetParticipatingGroupsResponseClientError", "moduleName": "WASmaxInGroupsGetParticipatingGroupsResponseClientError", - "kind": "error", + "kind": "client_error", + "errorArms": [ + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorRateOverlimit", + "code": 429, + "text": "rate-overlimit" + }, + { + "name": "IQErrorFallbackClient", + "codeMin": 400, + "codeMax": 499 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -54627,7 +65936,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -54643,14 +65953,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -54662,6 +65974,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -54673,14 +65990,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "rate-overlimit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "429" } ], "assertions": [ @@ -54692,6 +66011,11 @@ "kind": "attr", "name": "text", "value": "rate-overlimit" + }, + { + "kind": "attr", + "name": "code", + "value": "429" } ] }, @@ -54732,12 +66056,48 @@ { "tag": "GetParticipatingGroupsResponseServerError", "moduleName": "WASmaxInGroupsGetParticipatingGroupsResponseServerError", - "kind": "error", + "kind": "server_error", + "errorArms": [ + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorServiceUnavailable", + "code": 503, + "text": "service-unavailable" + }, + { + "name": "IQErrorPartialServerError", + "code": 530, + "text": "partial-server-error" + }, + { + "name": "IQErrorFallbackServer", + "codeMin": 500, + "codeMax": 599 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -54750,7 +66110,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -54766,14 +66127,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -54785,6 +66148,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -54796,14 +66164,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "assertions": [ @@ -54815,6 +66185,11 @@ "kind": "attr", "name": "text", "value": "service-unavailable" + }, + { + "kind": "attr", + "name": "code", + "value": "503" } ] }, @@ -54826,14 +66201,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "partial-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "530" } ], "assertions": [ @@ -54845,6 +66222,11 @@ "kind": "attr", "name": "text", "value": "partial-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "530" } ] }, @@ -54917,7 +66299,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "", @@ -54930,7 +66313,21 @@ "name": "addressingMode", "wireName": "addressing_mode", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_LID_PN", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "lid", + "value": "lid" + }, + { + "name": "pn", + "value": "pn" + } + ] + } } ], "sameNode": true @@ -55050,6 +66447,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -55062,7 +66473,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "", @@ -55075,7 +66487,21 @@ "name": "addressingMode", "wireName": "addressing_mode", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_LID_PN", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "lid", + "value": "lid" + }, + { + "name": "pn", + "value": "pn" + } + ] + } } ], "sameNode": true @@ -55189,12 +66615,53 @@ { "tag": "GetReportedMessagesResponseClientError", "moduleName": "WASmaxInGroupsGetReportedMessagesResponseClientError", - "kind": "error", + "kind": "client_error", + "errorArms": [ + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorNotAuthorized", + "code": 401, + "text": "not-authorized" + }, + { + "name": "IQErrorItemNotFound", + "code": 404, + "text": "item-not-found" + }, + { + "name": "IQErrorRateOverlimit", + "code": 429, + "text": "rate-overlimit" + }, + { + "name": "IQErrorLocked", + "code": 423, + "text": "locked" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -55207,7 +66674,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -55223,14 +66691,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -55242,6 +66712,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -55253,14 +66728,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-authorized" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "401" } ], "assertions": [ @@ -55272,6 +66749,11 @@ "kind": "attr", "name": "text", "value": "not-authorized" + }, + { + "kind": "attr", + "name": "code", + "value": "401" } ] }, @@ -55283,14 +66765,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "item-not-found" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "404" } ], "assertions": [ @@ -55302,6 +66786,11 @@ "kind": "attr", "name": "text", "value": "item-not-found" + }, + { + "kind": "attr", + "name": "code", + "value": "404" } ] }, @@ -55313,14 +66802,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "rate-overlimit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "429" } ], "assertions": [ @@ -55332,6 +66823,11 @@ "kind": "attr", "name": "text", "value": "rate-overlimit" + }, + { + "kind": "attr", + "name": "code", + "value": "429" } ] }, @@ -55343,14 +66839,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "locked" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "423" } ], "assertions": [ @@ -55362,6 +66860,11 @@ "kind": "attr", "name": "text", "value": "locked" + }, + { + "kind": "attr", + "name": "code", + "value": "423" } ] } @@ -55375,12 +66878,48 @@ { "tag": "GetReportedMessagesResponseServerError", "moduleName": "WASmaxInGroupsGetReportedMessagesResponseServerError", - "kind": "error", + "kind": "server_error", + "errorArms": [ + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorServiceUnavailable", + "code": 503, + "text": "service-unavailable" + }, + { + "name": "IQErrorPartialServerError", + "code": 530, + "text": "partial-server-error" + }, + { + "name": "IQErrorFallbackServer", + "codeMin": 500, + "codeMax": 599 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -55393,7 +66932,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -55409,14 +66949,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -55428,6 +66970,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -55439,14 +66986,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "assertions": [ @@ -55458,6 +67007,11 @@ "kind": "attr", "name": "text", "value": "service-unavailable" + }, + { + "kind": "attr", + "name": "code", + "value": "503" } ] }, @@ -55469,14 +67023,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "partial-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "530" } ], "assertions": [ @@ -55488,6 +67044,11 @@ "kind": "attr", "name": "text", "value": "partial-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "530" } ] }, @@ -55754,7 +67315,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ], "variants": [ @@ -55767,6 +67329,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -55779,7 +67355,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ] }, @@ -55792,6 +67369,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -55804,7 +67395,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ] }, @@ -55812,11 +67404,92 @@ "tag": "AcceptGroupAddResponseClientError", "moduleName": "WASmaxInGroupsAcceptGroupAddResponseClientError", "kind": "error", + "errorArms": [ + { + "name": "IQErrorAlreadyExists", + "code": 304, + "text": "already-exists" + }, + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorNotAuthorized", + "code": 401, + "text": "not-authorized" + }, + { + "name": "IQErrorForbidden", + "code": 403, + "text": "forbidden" + }, + { + "name": "IQErrorItemNotFound", + "code": 404, + "text": "item-not-found" + }, + { + "name": "IQErrorConflict", + "code": 409, + "text": "conflict" + }, + { + "name": "IQErrorGone", + "code": 410, + "text": "gone" + }, + { + "name": "IQErrorResourceLimit", + "code": 419, + "text": "resource-limit" + }, + { + "name": "IQErrorLocked", + "code": 423, + "text": "locked" + }, + { + "name": "IQErrorResourceConstraint", + "code": 500, + "text": "resource-constraint" + }, + { + "name": "IQErrorNotAllowed", + "code": 405, + "text": "not-allowed" + }, + { + "name": "IQErrorParentLinkedGroupsParticipantsResourceLimit", + "code": 412, + "text": "linked-groups-participants-resource-limit" + }, + { + "name": "IQErrorFallbackClient", + "codeMin": 400, + "codeMax": 499 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -55829,7 +67502,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -55845,14 +67519,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "already-exists" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "304" } ], "assertions": [ @@ -55864,6 +67540,11 @@ "kind": "attr", "name": "text", "value": "already-exists" + }, + { + "kind": "attr", + "name": "code", + "value": "304" } ] }, @@ -55875,14 +67556,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -55894,6 +67577,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -55905,14 +67593,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-authorized" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "401" } ], "assertions": [ @@ -55924,6 +67614,11 @@ "kind": "attr", "name": "text", "value": "not-authorized" + }, + { + "kind": "attr", + "name": "code", + "value": "401" } ] }, @@ -55935,14 +67630,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "forbidden" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "403" } ], "assertions": [ @@ -55954,6 +67651,11 @@ "kind": "attr", "name": "text", "value": "forbidden" + }, + { + "kind": "attr", + "name": "code", + "value": "403" } ] }, @@ -55965,14 +67667,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "item-not-found" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "404" } ], "assertions": [ @@ -55984,6 +67688,11 @@ "kind": "attr", "name": "text", "value": "item-not-found" + }, + { + "kind": "attr", + "name": "code", + "value": "404" } ] }, @@ -55995,14 +67704,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "conflict" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "409" } ], "assertions": [ @@ -56014,6 +67725,11 @@ "kind": "attr", "name": "text", "value": "conflict" + }, + { + "kind": "attr", + "name": "code", + "value": "409" } ] }, @@ -56025,14 +67741,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "gone" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "410" } ], "assertions": [ @@ -56044,6 +67762,11 @@ "kind": "attr", "name": "text", "value": "gone" + }, + { + "kind": "attr", + "name": "code", + "value": "410" } ] }, @@ -56055,14 +67778,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "resource-limit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "419" } ], "assertions": [ @@ -56074,6 +67799,11 @@ "kind": "attr", "name": "text", "value": "resource-limit" + }, + { + "kind": "attr", + "name": "code", + "value": "419" } ] }, @@ -56085,14 +67815,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "locked" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "423" } ], "assertions": [ @@ -56104,6 +67836,11 @@ "kind": "attr", "name": "text", "value": "locked" + }, + { + "kind": "attr", + "name": "code", + "value": "423" } ] }, @@ -56115,14 +67852,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "resource-constraint" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -56134,6 +67873,11 @@ "kind": "attr", "name": "text", "value": "resource-constraint" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -56145,14 +67889,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-allowed" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "405" } ], "assertions": [ @@ -56164,6 +67910,11 @@ "kind": "attr", "name": "text", "value": "not-allowed" + }, + { + "kind": "attr", + "name": "code", + "value": "405" } ] }, @@ -56175,14 +67926,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "linked-groups-participants-resource-limit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "412" } ], "assertions": [ @@ -56194,6 +67947,11 @@ "kind": "attr", "name": "text", "value": "linked-groups-participants-resource-limit" + }, + { + "kind": "attr", + "name": "code", + "value": "412" } ] }, @@ -56234,12 +67992,48 @@ { "tag": "AcceptGroupAddResponseServerError", "moduleName": "WASmaxInGroupsAcceptGroupAddResponseServerError", - "kind": "error", + "kind": "server_error", + "errorArms": [ + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorServiceUnavailable", + "code": 503, + "text": "service-unavailable" + }, + { + "name": "IQErrorPartialServerError", + "code": 530, + "text": "partial-server-error" + }, + { + "name": "IQErrorFallbackServer", + "codeMin": 500, + "codeMax": 599 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -56252,7 +68046,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -56268,14 +68063,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -56287,6 +68084,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -56298,14 +68100,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "assertions": [ @@ -56317,6 +68121,11 @@ "kind": "attr", "name": "text", "value": "service-unavailable" + }, + { + "kind": "attr", + "name": "code", + "value": "503" } ] }, @@ -56328,14 +68137,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "partial-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "530" } ], "assertions": [ @@ -56347,6 +68158,11 @@ "kind": "attr", "name": "text", "value": "partial-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "530" } ] }, @@ -56419,7 +68235,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ], "variants": [ @@ -56432,10 +68249,24 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", "value": "result" + }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] } ], "fields": [ @@ -56444,19 +68275,56 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ] }, { "tag": "AcknowledgeGroupResponseClientError", "moduleName": "WASmaxInGroupsAcknowledgeGroupResponseClientError", - "kind": "error", + "kind": "client_error", + "errorArms": [ + { + "name": "IQErrorItemNotFound", + "code": 404, + "text": "item-not-found" + }, + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorRateOverlimit", + "code": 429, + "text": "rate-overlimit" + }, + { + "name": "IQErrorFallbackClient", + "codeMin": 400, + "codeMax": 499 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -56469,7 +68337,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -56485,14 +68354,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "item-not-found" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "404" } ], "assertions": [ @@ -56504,6 +68375,11 @@ "kind": "attr", "name": "text", "value": "item-not-found" + }, + { + "kind": "attr", + "name": "code", + "value": "404" } ] }, @@ -56515,14 +68391,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -56534,6 +68412,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -56545,14 +68428,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "rate-overlimit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "429" } ], "assertions": [ @@ -56564,6 +68449,11 @@ "kind": "attr", "name": "text", "value": "rate-overlimit" + }, + { + "kind": "attr", + "name": "code", + "value": "429" } ] }, @@ -56604,12 +68494,48 @@ { "tag": "AcknowledgeGroupResponseServerError", "moduleName": "WASmaxInGroupsAcknowledgeGroupResponseServerError", - "kind": "error", + "kind": "server_error", + "errorArms": [ + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorServiceUnavailable", + "code": 503, + "text": "service-unavailable" + }, + { + "name": "IQErrorPartialServerError", + "code": 530, + "text": "partial-server-error" + }, + { + "name": "IQErrorFallbackServer", + "codeMin": 500, + "codeMax": 599 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -56622,7 +68548,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -56638,14 +68565,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -56657,6 +68586,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -56668,14 +68602,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "assertions": [ @@ -56687,6 +68623,11 @@ "kind": "attr", "name": "text", "value": "service-unavailable" + }, + { + "kind": "attr", + "name": "code", + "value": "503" } ] }, @@ -56698,14 +68639,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "partial-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "530" } ], "assertions": [ @@ -56717,6 +68660,11 @@ "kind": "attr", "name": "text", "value": "partial-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "530" } ] }, @@ -56813,7 +68761,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "", @@ -56826,7 +68775,21 @@ "name": "addressingMode", "wireName": "addressing_mode", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_LID_PN", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "lid", + "value": "lid" + }, + { + "name": "pn", + "value": "pn" + } + ] + } } ], "sameNode": true @@ -56907,7 +68870,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "421" }, { "method": "maybeAttrEnum", @@ -56940,7 +68904,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "401" } ], "assertions": [ @@ -56963,7 +68928,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "402" } ], "assertions": [ @@ -56986,7 +68952,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "403" }, { "method": "maybeAttrString", @@ -57019,7 +68986,8 @@ "name": "addressable", "wireName": "addressable", "type": "string", - "required": true + "required": true, + "literalValue": "false" } ], "sameNode": true @@ -57045,7 +69013,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "451" } ], "assertions": [ @@ -57068,7 +69037,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "404" } ], "assertions": [ @@ -57091,7 +69061,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "408" } ], "assertions": [ @@ -57114,7 +69085,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "409" } ], "assertions": [ @@ -57137,7 +69109,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "419" } ], "assertions": [ @@ -57160,7 +69133,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -57183,7 +69157,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "406" } ], "assertions": [ @@ -57206,7 +69181,8 @@ "name": "addressable", "wireName": "addressable", "type": "string", - "required": true + "required": true, + "literalValue": "false" } ], "assertions": [ @@ -57229,7 +69205,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "417" } ], "assertions": [ @@ -57252,7 +69229,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "431" } ], "assertions": [ @@ -57275,7 +69253,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "432" } ], "assertions": [ @@ -57324,7 +69303,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "403" }, { "method": "maybeAttrString", @@ -57357,7 +69337,8 @@ "name": "addressable", "wireName": "addressable", "type": "string", - "required": true + "required": true, + "literalValue": "false" } ], "sameNode": true @@ -57383,7 +69364,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "451" } ], "assertions": [ @@ -57406,7 +69388,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "404" } ], "assertions": [ @@ -57450,10 +69433,24 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", "value": "result" + }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] } ], "fields": [ @@ -57462,7 +69459,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "", @@ -57475,7 +69473,21 @@ "name": "addressingMode", "wireName": "addressing_mode", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_LID_PN", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "lid", + "value": "lid" + }, + { + "name": "pn", + "value": "pn" + } + ] + } } ], "sameNode": true @@ -57556,7 +69568,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "421" }, { "method": "maybeAttrEnum", @@ -57589,7 +69602,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "401" } ], "assertions": [ @@ -57612,7 +69626,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "402" } ], "assertions": [ @@ -57635,7 +69650,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "403" }, { "method": "maybeAttrString", @@ -57668,7 +69684,8 @@ "name": "addressable", "wireName": "addressable", "type": "string", - "required": true + "required": true, + "literalValue": "false" } ], "sameNode": true @@ -57694,7 +69711,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "451" } ], "assertions": [ @@ -57717,7 +69735,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "404" } ], "assertions": [ @@ -57740,7 +69759,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "408" } ], "assertions": [ @@ -57763,7 +69783,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "409" } ], "assertions": [ @@ -57786,7 +69807,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "419" } ], "assertions": [ @@ -57809,7 +69831,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -57832,7 +69855,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "406" } ], "assertions": [ @@ -57855,7 +69879,8 @@ "name": "addressable", "wireName": "addressable", "type": "string", - "required": true + "required": true, + "literalValue": "false" } ], "assertions": [ @@ -57878,7 +69903,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "417" } ], "assertions": [ @@ -57901,7 +69927,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "431" } ], "assertions": [ @@ -57924,7 +69951,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "432" } ], "assertions": [ @@ -57973,7 +70001,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "403" }, { "method": "maybeAttrString", @@ -58006,7 +70035,8 @@ "name": "addressable", "wireName": "addressable", "type": "string", - "required": true + "required": true, + "literalValue": "false" } ], "sameNode": true @@ -58032,7 +70062,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "451" } ], "assertions": [ @@ -58055,7 +70086,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "404" } ], "assertions": [ @@ -58093,12 +70125,83 @@ { "tag": "AddParticipantsResponseClientError", "moduleName": "WASmaxInGroupsAddParticipantsResponseClientError", - "kind": "error", + "kind": "client_error", + "errorArms": [ + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorItemNotFound", + "code": 404, + "text": "item-not-found" + }, + { + "name": "IQErrorNotAuthorized", + "code": 401, + "text": "not-authorized" + }, + { + "name": "IQErrorForbidden", + "code": 403, + "text": "forbidden" + }, + { + "name": "AddParticipantTimeRateLimit", + "code": 429, + "text": "rate-overlimit" + }, + { + "name": "AddParticipantCountRateLimit", + "code": 429, + "text": "rate-overlimit" + }, + { + "name": "IQErrorRateOverlimit", + "code": 429, + "text": "rate-overlimit" + }, + { + "name": "IQErrorNotAllowed", + "code": 405, + "text": "not-allowed" + }, + { + "name": "IQErrorLocked", + "code": 423, + "text": "locked" + }, + { + "name": "IQErrorParentGroupSuspended", + "code": 416, + "text": "parent-group-suspended" + }, + { + "name": "IQErrorFallbackClient", + "codeMin": 400, + "codeMax": 499 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -58111,7 +70214,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -58127,14 +70231,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -58146,6 +70252,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -58157,14 +70268,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "item-not-found" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "404" } ], "assertions": [ @@ -58176,6 +70289,11 @@ "kind": "attr", "name": "text", "value": "item-not-found" + }, + { + "kind": "attr", + "name": "code", + "value": "404" } ] }, @@ -58187,14 +70305,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-authorized" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "401" } ], "assertions": [ @@ -58206,6 +70326,11 @@ "kind": "attr", "name": "text", "value": "not-authorized" + }, + { + "kind": "attr", + "name": "code", + "value": "401" } ] }, @@ -58217,14 +70342,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "forbidden" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "403" } ], "assertions": [ @@ -58236,6 +70363,11 @@ "kind": "attr", "name": "text", "value": "forbidden" + }, + { + "kind": "attr", + "name": "code", + "value": "403" } ] }, @@ -58247,14 +70379,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "rate-overlimit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "429" }, { "method": "", @@ -58277,7 +70411,21 @@ "name": "type", "wireName": "type", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_GROUP_USER", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "group", + "value": "group" + }, + { + "name": "user", + "value": "user" + } + ] + } } ], "assertions": [ @@ -58322,6 +70470,11 @@ "kind": "attr", "name": "text", "value": "rate-overlimit" + }, + { + "kind": "attr", + "name": "code", + "value": "429" } ] }, @@ -58333,14 +70486,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "rate-overlimit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "429" } ], "assertions": [ @@ -58352,6 +70507,11 @@ "kind": "attr", "name": "text", "value": "rate-overlimit" + }, + { + "kind": "attr", + "name": "code", + "value": "429" } ] }, @@ -58363,14 +70523,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-allowed" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "405" } ], "assertions": [ @@ -58382,6 +70544,11 @@ "kind": "attr", "name": "text", "value": "not-allowed" + }, + { + "kind": "attr", + "name": "code", + "value": "405" } ] }, @@ -58393,14 +70560,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "locked" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "423" } ], "assertions": [ @@ -58412,6 +70581,11 @@ "kind": "attr", "name": "text", "value": "locked" + }, + { + "kind": "attr", + "name": "code", + "value": "423" } ] }, @@ -58423,14 +70597,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "parent-group-suspended" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "416" } ], "assertions": [ @@ -58442,6 +70618,11 @@ "kind": "attr", "name": "text", "value": "parent-group-suspended" + }, + { + "kind": "attr", + "name": "code", + "value": "416" } ] }, @@ -58482,12 +70663,48 @@ { "tag": "AddParticipantsResponseServerError", "moduleName": "WASmaxInGroupsAddParticipantsResponseServerError", - "kind": "error", + "kind": "server_error", + "errorArms": [ + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorServiceUnavailable", + "code": 503, + "text": "service-unavailable" + }, + { + "name": "IQErrorPartialServerError", + "code": 530, + "text": "partial-server-error" + }, + { + "name": "IQErrorFallbackServer", + "codeMin": 500, + "codeMax": 599 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -58500,7 +70717,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -58516,14 +70734,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -58535,6 +70755,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -58546,14 +70771,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "assertions": [ @@ -58565,6 +70792,11 @@ "kind": "attr", "name": "text", "value": "service-unavailable" + }, + { + "kind": "attr", + "name": "code", + "value": "503" } ] }, @@ -58576,14 +70808,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "partial-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "530" } ], "assertions": [ @@ -58595,6 +70829,11 @@ "kind": "attr", "name": "text", "value": "partial-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "530" } ] }, @@ -58681,7 +70920,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "", @@ -58694,7 +70934,21 @@ "name": "addressingMode", "wireName": "addressing_mode", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_LID_PN", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "lid", + "value": "lid" + }, + { + "name": "pn", + "value": "pn" + } + ] + } } ], "sameNode": true @@ -58743,7 +70997,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "404" } ], "assertions": [ @@ -58766,7 +71021,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "401" } ], "assertions": [ @@ -58800,6 +71056,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -58812,7 +71082,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "", @@ -58825,7 +71096,21 @@ "name": "addressingMode", "wireName": "addressing_mode", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_LID_PN", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "lid", + "value": "lid" + }, + { + "name": "pn", + "value": "pn" + } + ] + } } ], "sameNode": true @@ -58874,7 +71159,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "404" } ], "assertions": [ @@ -58897,7 +71183,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "401" } ], "assertions": [ @@ -58925,12 +71212,53 @@ { "tag": "CancelGroupMembershipRequestsResponseClientError", "moduleName": "WASmaxInGroupsCancelGroupMembershipRequestsResponseClientError", - "kind": "error", + "kind": "client_error", + "errorArms": [ + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorItemNotFound", + "code": 404, + "text": "item-not-found" + }, + { + "name": "IQErrorLocked", + "code": 423, + "text": "locked" + }, + { + "name": "IQErrorRateOverlimit", + "code": 429, + "text": "rate-overlimit" + }, + { + "name": "IQErrorFallbackClient", + "codeMin": 400, + "codeMax": 499 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -58943,7 +71271,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -58959,14 +71288,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -58978,6 +71309,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -58989,14 +71325,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "item-not-found" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "404" } ], "assertions": [ @@ -59008,6 +71346,11 @@ "kind": "attr", "name": "text", "value": "item-not-found" + }, + { + "kind": "attr", + "name": "code", + "value": "404" } ] }, @@ -59019,14 +71362,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "locked" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "423" } ], "assertions": [ @@ -59038,6 +71383,11 @@ "kind": "attr", "name": "text", "value": "locked" + }, + { + "kind": "attr", + "name": "code", + "value": "423" } ] }, @@ -59049,14 +71399,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "rate-overlimit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "429" } ], "assertions": [ @@ -59068,6 +71420,11 @@ "kind": "attr", "name": "text", "value": "rate-overlimit" + }, + { + "kind": "attr", + "name": "code", + "value": "429" } ] }, @@ -59108,12 +71465,48 @@ { "tag": "CancelGroupMembershipRequestsResponseServerError", "moduleName": "WASmaxInGroupsCancelGroupMembershipRequestsResponseServerError", - "kind": "error", + "kind": "server_error", + "errorArms": [ + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorServiceUnavailable", + "code": 503, + "text": "service-unavailable" + }, + { + "name": "IQErrorPartialServerError", + "code": 530, + "text": "partial-server-error" + }, + { + "name": "IQErrorFallbackServer", + "codeMin": 500, + "codeMax": 599 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -59126,7 +71519,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -59142,14 +71536,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -59161,6 +71557,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -59172,14 +71573,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "assertions": [ @@ -59191,6 +71594,11 @@ "kind": "attr", "name": "text", "value": "service-unavailable" + }, + { + "kind": "attr", + "name": "code", + "value": "503" } ] }, @@ -59202,14 +71610,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "partial-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "530" } ], "assertions": [ @@ -59221,6 +71631,11 @@ "kind": "attr", "name": "text", "value": "partial-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "530" } ] }, @@ -59491,7 +71906,7 @@ "assertions": [], "fields": [ { - "method": "attrJidWithType", + "method": "literalJid", "name": "from", "wireName": "from", "type": "jid", @@ -59502,7 +71917,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "attrString", @@ -59573,7 +71989,25 @@ "name": "createCtx", "wireName": "create_ctx", "type": "enum", - "required": false + "required": false, + "enumRef": { + "name": "ENUM_E2EEMIGRATION_REGULAR_RTC", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "e2ee_migration", + "value": "e2ee_migration" + }, + { + "name": "regular", + "value": "regular" + }, + { + "name": "rtc", + "value": "rtc" + } + ] + } } ], "repeats": false @@ -59656,7 +72090,21 @@ "name": "addressingMode", "wireName": "addressing_mode", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_LID_PN", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "lid", + "value": "lid" + }, + { + "name": "pn", + "value": "pn" + } + ] + } } ], "repeats": false @@ -59985,7 +72433,8 @@ "name": "defaultMembershipApprovalMode", "wireName": "default_membership_approval_mode", "type": "string", - "required": true + "required": true, + "literalValue": "request_required" } ], "sameNode": true @@ -60046,6 +72495,7 @@ "wireName": "state", "type": "string", "required": true, + "literalValue": "on", "sourcePath": [ "group_join" ] @@ -60123,10 +72573,10 @@ "name": "CreateParticipantAddedResponse", "fields": [ { - "method": "attrJidWithType", + "method": "attrJidEnum", "name": "jid", "wireName": "jid", - "type": "jid", + "type": "jid_typed", "required": true }, { @@ -60175,7 +72625,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "417" } ], "assertions": [ @@ -60198,7 +72649,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "401" } ], "assertions": [ @@ -60221,7 +72673,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "403" }, { "method": "maybeAttrString", @@ -60254,7 +72707,8 @@ "name": "addressable", "wireName": "addressable", "type": "string", - "required": true + "required": true, + "literalValue": "false" } ], "sameNode": true @@ -60280,7 +72734,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "451" } ], "assertions": [ @@ -60303,7 +72758,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "404" } ], "assertions": [ @@ -60326,7 +72782,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -60349,7 +72806,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "406" } ], "assertions": [ @@ -60372,7 +72830,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "419" } ], "assertions": [ @@ -60395,7 +72854,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "431" } ], "assertions": [ @@ -60418,7 +72878,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "432" } ], "assertions": [ @@ -60441,7 +72902,21 @@ "name": "type", "wireName": "type", "type": "enum", - "required": false + "required": false, + "enumRef": { + "name": "ENUM_ADMIN_SUPERADMIN", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "admin", + "value": "admin" + }, + { + "name": "superadmin", + "value": "superadmin" + } + ] + } }, { "method": "maybeAttrInt", @@ -60461,7 +72936,8 @@ "name": "addressable", "wireName": "addressable", "type": "string", - "required": true + "required": true, + "literalValue": "false" } ], "sameNode": true @@ -60508,7 +72984,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "403" }, { "method": "maybeAttrString", @@ -60541,7 +73018,8 @@ "name": "addressable", "wireName": "addressable", "type": "string", - "required": true + "required": true, + "literalValue": "false" } ], "sameNode": true @@ -60567,7 +73045,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "451" } ], "assertions": [ @@ -60590,7 +73069,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "404" } ], "assertions": [ @@ -60638,11 +73118,18 @@ "kind": "attr", "name": "type", "value": "result" + }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] } ], "fields": [ { - "method": "attrJidWithType", + "method": "literalJid", "name": "from", "wireName": "from", "type": "jid", @@ -60653,7 +73140,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "attrString", @@ -60724,7 +73212,25 @@ "name": "createCtx", "wireName": "create_ctx", "type": "enum", - "required": false + "required": false, + "enumRef": { + "name": "ENUM_E2EEMIGRATION_REGULAR_RTC", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "e2ee_migration", + "value": "e2ee_migration" + }, + { + "name": "regular", + "value": "regular" + }, + { + "name": "rtc", + "value": "rtc" + } + ] + } } ], "repeats": false @@ -60807,7 +73313,21 @@ "name": "addressingMode", "wireName": "addressing_mode", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_LID_PN", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "lid", + "value": "lid" + }, + { + "name": "pn", + "value": "pn" + } + ] + } } ], "repeats": false @@ -61136,7 +73656,8 @@ "name": "defaultMembershipApprovalMode", "wireName": "default_membership_approval_mode", "type": "string", - "required": true + "required": true, + "literalValue": "request_required" } ], "sameNode": true @@ -61197,6 +73718,7 @@ "wireName": "state", "type": "string", "required": true, + "literalValue": "on", "sourcePath": [ "group_join" ] @@ -61274,10 +73796,10 @@ "name": "CreateParticipantAddedResponse", "fields": [ { - "method": "attrJidWithType", + "method": "attrJidEnum", "name": "jid", "wireName": "jid", - "type": "jid", + "type": "jid_typed", "required": true }, { @@ -61326,7 +73848,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "417" } ], "assertions": [ @@ -61349,7 +73872,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "401" } ], "assertions": [ @@ -61372,7 +73896,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "403" }, { "method": "maybeAttrString", @@ -61405,7 +73930,8 @@ "name": "addressable", "wireName": "addressable", "type": "string", - "required": true + "required": true, + "literalValue": "false" } ], "sameNode": true @@ -61431,7 +73957,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "451" } ], "assertions": [ @@ -61454,7 +73981,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "404" } ], "assertions": [ @@ -61477,7 +74005,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -61500,7 +74029,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "406" } ], "assertions": [ @@ -61523,7 +74053,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "419" } ], "assertions": [ @@ -61546,7 +74077,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "431" } ], "assertions": [ @@ -61569,7 +74101,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "432" } ], "assertions": [ @@ -61592,7 +74125,21 @@ "name": "type", "wireName": "type", "type": "enum", - "required": false + "required": false, + "enumRef": { + "name": "ENUM_ADMIN_SUPERADMIN", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "admin", + "value": "admin" + }, + { + "name": "superadmin", + "value": "superadmin" + } + ] + } }, { "method": "maybeAttrInt", @@ -61612,7 +74159,8 @@ "name": "addressable", "wireName": "addressable", "type": "string", - "required": true + "required": true, + "literalValue": "false" } ], "sameNode": true @@ -61659,7 +74207,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "403" }, { "method": "maybeAttrString", @@ -61692,7 +74241,8 @@ "name": "addressable", "wireName": "addressable", "type": "string", - "required": true + "required": true, + "literalValue": "false" } ], "sameNode": true @@ -61718,7 +74268,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "451" } ], "assertions": [ @@ -61741,7 +74292,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "404" } ], "assertions": [ @@ -61779,7 +74331,7 @@ { "tag": "CreateResponseGroupAlreadyExists", "moduleName": "WASmaxInGroupsCreateResponseGroupAlreadyExists", - "kind": "error", + "kind": "alternative", "assertions": [ { "kind": "tag", @@ -61789,11 +74341,18 @@ "kind": "attr", "name": "type", "value": "result" + }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] } ], "fields": [ { - "method": "attrJidWithType", + "method": "literalJid", "name": "from", "wireName": "from", "type": "jid", @@ -61804,7 +74363,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "attrGroupJid", @@ -61822,11 +74382,92 @@ "tag": "CreateResponseClientError", "moduleName": "WASmaxInGroupsCreateResponseClientError", "kind": "error", + "errorArms": [ + { + "name": "IQErrorForbidden", + "code": 403, + "text": "forbidden" + }, + { + "name": "IQErrorResourceConstraint", + "code": 500, + "text": "resource-constraint" + }, + { + "name": "IQErrorItemNotFound", + "code": 404, + "text": "item-not-found" + }, + { + "name": "IQErrorResourceLimit", + "code": 419, + "text": "resource-limit" + }, + { + "name": "IQErrorNotAcceptable", + "code": 406, + "text": "not-acceptable" + }, + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "AddParticipantTimeRateLimit", + "code": 429, + "text": "rate-overlimit" + }, + { + "name": "AddParticipantCountRateLimit", + "code": 429, + "text": "rate-overlimit" + }, + { + "name": "IQErrorRateOverlimit", + "code": 429, + "text": "rate-overlimit" + }, + { + "name": "IQErrorNotAllowed", + "code": 405, + "text": "not-allowed" + }, + { + "name": "IQErrorParentLinkedGroupsParticipantsResourceLimit", + "code": 412, + "text": "linked-groups-participants-resource-limit" + }, + { + "name": "IQErrorParentGroupSuspended", + "code": 416, + "text": "parent-group-suspended" + }, + { + "name": "IQErrorFallbackClient", + "codeMin": 400, + "codeMax": 499 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -61839,7 +74480,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -61855,14 +74497,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "forbidden" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "403" } ], "assertions": [ @@ -61874,6 +74518,11 @@ "kind": "attr", "name": "text", "value": "forbidden" + }, + { + "kind": "attr", + "name": "code", + "value": "403" } ] }, @@ -61885,14 +74534,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "resource-constraint" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -61904,6 +74555,11 @@ "kind": "attr", "name": "text", "value": "resource-constraint" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -61915,14 +74571,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "item-not-found" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "404" } ], "assertions": [ @@ -61934,6 +74592,11 @@ "kind": "attr", "name": "text", "value": "item-not-found" + }, + { + "kind": "attr", + "name": "code", + "value": "404" } ] }, @@ -61945,14 +74608,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "resource-limit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "419" } ], "assertions": [ @@ -61964,6 +74629,11 @@ "kind": "attr", "name": "text", "value": "resource-limit" + }, + { + "kind": "attr", + "name": "code", + "value": "419" } ] }, @@ -61975,14 +74645,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-acceptable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "406" }, { "method": "child", @@ -62018,6 +74690,11 @@ "kind": "attr", "name": "text", "value": "not-acceptable" + }, + { + "kind": "attr", + "name": "code", + "value": "406" } ] }, @@ -62029,14 +74706,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -62048,6 +74727,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -62059,14 +74743,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "rate-overlimit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "429" }, { "method": "", @@ -62089,7 +74775,21 @@ "name": "type", "wireName": "type", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_GROUP_USER", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "group", + "value": "group" + }, + { + "name": "user", + "value": "user" + } + ] + } } ], "assertions": [ @@ -62134,6 +74834,11 @@ "kind": "attr", "name": "text", "value": "rate-overlimit" + }, + { + "kind": "attr", + "name": "code", + "value": "429" } ] }, @@ -62145,14 +74850,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "rate-overlimit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "429" } ], "assertions": [ @@ -62164,6 +74871,11 @@ "kind": "attr", "name": "text", "value": "rate-overlimit" + }, + { + "kind": "attr", + "name": "code", + "value": "429" } ] }, @@ -62175,14 +74887,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-allowed" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "405" } ], "assertions": [ @@ -62194,6 +74908,11 @@ "kind": "attr", "name": "text", "value": "not-allowed" + }, + { + "kind": "attr", + "name": "code", + "value": "405" } ] }, @@ -62205,14 +74924,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "linked-groups-participants-resource-limit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "412" } ], "assertions": [ @@ -62224,6 +74945,11 @@ "kind": "attr", "name": "text", "value": "linked-groups-participants-resource-limit" + }, + { + "kind": "attr", + "name": "code", + "value": "412" } ] }, @@ -62235,14 +74961,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "parent-group-suspended" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "416" } ], "assertions": [ @@ -62254,6 +74982,11 @@ "kind": "attr", "name": "text", "value": "parent-group-suspended" + }, + { + "kind": "attr", + "name": "code", + "value": "416" } ] }, @@ -62294,12 +75027,48 @@ { "tag": "CreateResponseServerError", "moduleName": "WASmaxInGroupsCreateResponseServerError", - "kind": "error", + "kind": "server_error", + "errorArms": [ + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorServiceUnavailable", + "code": 503, + "text": "service-unavailable" + }, + { + "name": "IQErrorPartialServerError", + "code": 530, + "text": "partial-server-error" + }, + { + "name": "IQErrorFallbackServer", + "codeMin": 500, + "codeMax": 599 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -62312,7 +75081,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -62328,14 +75098,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -62347,6 +75119,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -62358,14 +75135,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "assertions": [ @@ -62377,6 +75156,11 @@ "kind": "attr", "name": "text", "value": "service-unavailable" + }, + { + "kind": "attr", + "name": "code", + "value": "503" } ] }, @@ -62388,14 +75172,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "partial-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "530" } ], "assertions": [ @@ -62407,6 +75193,11 @@ "kind": "attr", "name": "text", "value": "partial-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "530" } ] }, @@ -62526,7 +75317,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "", @@ -62539,7 +75331,21 @@ "name": "addressingMode", "wireName": "addressing_mode", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_LID_PN", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "lid", + "value": "lid" + }, + { + "name": "pn", + "value": "pn" + } + ] + } } ], "sameNode": true @@ -62556,7 +75362,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": false + "required": false, + "literalValue": "406" } ], "repeats": false, @@ -62575,6 +75382,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -62634,7 +75455,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "", @@ -62647,7 +75469,21 @@ "name": "addressingMode", "wireName": "addressing_mode", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_LID_PN", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "lid", + "value": "lid" + }, + { + "name": "pn", + "value": "pn" + } + ] + } } ], "sameNode": true @@ -62664,7 +75500,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": false + "required": false, + "literalValue": "406" } ], "repeats": false, @@ -62683,6 +75520,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -62695,7 +75546,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "", @@ -62708,7 +75560,21 @@ "name": "addressingMode", "wireName": "addressing_mode", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_LID_PN", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "lid", + "value": "lid" + }, + { + "name": "pn", + "value": "pn" + } + ] + } } ], "sameNode": true @@ -62741,7 +75607,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "401" } ], "assertions": [ @@ -62764,7 +75631,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "404" } ], "assertions": [ @@ -62787,7 +75655,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "409" } ], "assertions": [ @@ -62810,7 +75679,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "405" } ], "assertions": [ @@ -62833,7 +75703,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "419" } ], "assertions": [ @@ -62856,7 +75727,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -62879,7 +75751,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "406" } ], "assertions": [ @@ -62902,7 +75775,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -62930,12 +75804,68 @@ { "tag": "CreateSubGroupSuggestionResponseClientError", "moduleName": "WASmaxInGroupsCreateSubGroupSuggestionResponseClientError", - "kind": "error", + "kind": "client_error", + "errorArms": [ + { + "name": "IQErrorForbidden", + "code": 403, + "text": "forbidden" + }, + { + "name": "IQErrorItemNotFound", + "code": 404, + "text": "item-not-found" + }, + { + "name": "IQErrorResourceLimit", + "code": 419, + "text": "resource-limit" + }, + { + "name": "IQErrorNotAcceptable", + "code": 406, + "text": "not-acceptable" + }, + { + "name": "IQErrorRateOverlimit", + "code": 429, + "text": "rate-overlimit" + }, + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorNotAllowed", + "code": 405, + "text": "not-allowed" + }, + { + "name": "IQErrorFallbackClient", + "codeMin": 400, + "codeMax": 499 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -62948,7 +75878,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -62964,14 +75895,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "forbidden" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "403" } ], "assertions": [ @@ -62983,6 +75916,11 @@ "kind": "attr", "name": "text", "value": "forbidden" + }, + { + "kind": "attr", + "name": "code", + "value": "403" } ] }, @@ -62994,14 +75932,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "item-not-found" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "404" } ], "assertions": [ @@ -63013,6 +75953,11 @@ "kind": "attr", "name": "text", "value": "item-not-found" + }, + { + "kind": "attr", + "name": "code", + "value": "404" } ] }, @@ -63024,14 +75969,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "resource-limit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "419" } ], "assertions": [ @@ -63043,6 +75990,11 @@ "kind": "attr", "name": "text", "value": "resource-limit" + }, + { + "kind": "attr", + "name": "code", + "value": "419" } ] }, @@ -63054,14 +76006,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-acceptable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "406" }, { "method": "child", @@ -63097,6 +76051,11 @@ "kind": "attr", "name": "text", "value": "not-acceptable" + }, + { + "kind": "attr", + "name": "code", + "value": "406" } ] }, @@ -63108,14 +76067,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "rate-overlimit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "429" } ], "assertions": [ @@ -63127,6 +76088,11 @@ "kind": "attr", "name": "text", "value": "rate-overlimit" + }, + { + "kind": "attr", + "name": "code", + "value": "429" } ] }, @@ -63138,14 +76104,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -63157,6 +76125,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -63168,14 +76141,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-allowed" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "405" } ], "assertions": [ @@ -63187,6 +76162,11 @@ "kind": "attr", "name": "text", "value": "not-allowed" + }, + { + "kind": "attr", + "name": "code", + "value": "405" } ] }, @@ -63227,12 +76207,48 @@ { "tag": "CreateSubGroupSuggestionResponseServerError", "moduleName": "WASmaxInGroupsCreateSubGroupSuggestionResponseServerError", - "kind": "error", + "kind": "server_error", + "errorArms": [ + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorServiceUnavailable", + "code": 503, + "text": "service-unavailable" + }, + { + "name": "IQErrorPartialServerError", + "code": 530, + "text": "partial-server-error" + }, + { + "name": "IQErrorFallbackServer", + "codeMin": 500, + "codeMax": 599 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -63245,7 +76261,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -63261,14 +76278,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -63280,6 +76299,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -63291,14 +76315,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "assertions": [ @@ -63310,6 +76336,11 @@ "kind": "attr", "name": "text", "value": "service-unavailable" + }, + { + "kind": "attr", + "name": "code", + "value": "503" } ] }, @@ -63321,14 +76352,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "partial-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "530" } ], "assertions": [ @@ -63340,6 +76373,11 @@ "kind": "attr", "name": "text", "value": "partial-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "530" } ] }, @@ -63412,7 +76450,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ], "variants": [ @@ -63425,6 +76464,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -63437,19 +76490,51 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ] }, { "tag": "DeleteParentGroupResponseClientError", "moduleName": "WASmaxInGroupsDeleteParentGroupResponseClientError", - "kind": "error", + "kind": "client_error", + "errorArms": [ + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorNotAuthorized", + "code": 401, + "text": "not-authorized" + }, + { + "name": "IQErrorItemNotFound", + "code": 404, + "text": "item-not-found" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -63462,7 +76547,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -63478,14 +76564,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -63497,6 +76585,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -63508,14 +76601,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-authorized" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "401" } ], "assertions": [ @@ -63527,6 +76622,11 @@ "kind": "attr", "name": "text", "value": "not-authorized" + }, + { + "kind": "attr", + "name": "code", + "value": "401" } ] }, @@ -63538,14 +76638,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "item-not-found" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "404" } ], "assertions": [ @@ -63557,6 +76659,11 @@ "kind": "attr", "name": "text", "value": "item-not-found" + }, + { + "kind": "attr", + "name": "code", + "value": "404" } ] } @@ -63570,12 +76677,48 @@ { "tag": "DeleteParentGroupResponseServerError", "moduleName": "WASmaxInGroupsDeleteParentGroupResponseServerError", - "kind": "error", + "kind": "server_error", + "errorArms": [ + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorServiceUnavailable", + "code": 503, + "text": "service-unavailable" + }, + { + "name": "IQErrorPartialServerError", + "code": 530, + "text": "partial-server-error" + }, + { + "name": "IQErrorFallbackServer", + "codeMin": 500, + "codeMax": 599 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -63588,7 +76731,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -63604,14 +76748,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -63623,6 +76769,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -63634,14 +76785,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "assertions": [ @@ -63653,6 +76806,11 @@ "kind": "attr", "name": "text", "value": "service-unavailable" + }, + { + "kind": "attr", + "name": "code", + "value": "503" } ] }, @@ -63664,14 +76822,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "partial-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "530" } ], "assertions": [ @@ -63683,6 +76843,11 @@ "kind": "attr", "name": "text", "value": "partial-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "530" } ] }, @@ -63766,7 +76931,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ], "variants": [ @@ -63779,6 +76945,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -63791,7 +76971,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ] }, @@ -63804,6 +76985,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -63816,7 +77011,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ] }, @@ -63824,11 +77020,82 @@ "tag": "JoinLinkedGroupResponseClientError", "moduleName": "WASmaxInGroupsJoinLinkedGroupResponseClientError", "kind": "error", + "errorArms": [ + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorForbidden", + "code": 403, + "text": "forbidden" + }, + { + "name": "IQErrorItemNotFound", + "code": 404, + "text": "item-not-found" + }, + { + "name": "IQErrorNotAllowed", + "code": 405, + "text": "not-allowed" + }, + { + "name": "IQErrorNotAcceptable", + "code": 406, + "text": "not-acceptable" + }, + { + "name": "IQErrorConflict", + "code": 409, + "text": "conflict" + }, + { + "name": "IQErrorResourceLimit", + "code": 419, + "text": "resource-limit" + }, + { + "name": "IQErrorNotAuthorized", + "code": 401, + "text": "not-authorized" + }, + { + "name": "IQErrorUpgradeRequired", + "code": 426, + "text": "upgrade-required" + }, + { + "name": "IQErrorAlreadyExists", + "code": 304, + "text": "already-exists" + }, + { + "name": "IQErrorFallbackClient", + "codeMin": 400, + "codeMax": 499 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -63841,7 +77108,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -63857,14 +77125,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -63876,6 +77146,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -63887,14 +77162,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "forbidden" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "403" } ], "assertions": [ @@ -63906,6 +77183,11 @@ "kind": "attr", "name": "text", "value": "forbidden" + }, + { + "kind": "attr", + "name": "code", + "value": "403" } ] }, @@ -63917,14 +77199,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "item-not-found" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "404" } ], "assertions": [ @@ -63936,6 +77220,11 @@ "kind": "attr", "name": "text", "value": "item-not-found" + }, + { + "kind": "attr", + "name": "code", + "value": "404" } ] }, @@ -63947,14 +77236,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-allowed" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "405" } ], "assertions": [ @@ -63966,6 +77257,11 @@ "kind": "attr", "name": "text", "value": "not-allowed" + }, + { + "kind": "attr", + "name": "code", + "value": "405" } ] }, @@ -63977,14 +77273,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-acceptable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "406" }, { "method": "child", @@ -64020,6 +77318,11 @@ "kind": "attr", "name": "text", "value": "not-acceptable" + }, + { + "kind": "attr", + "name": "code", + "value": "406" } ] }, @@ -64031,14 +77334,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "conflict" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "409" } ], "assertions": [ @@ -64050,6 +77355,11 @@ "kind": "attr", "name": "text", "value": "conflict" + }, + { + "kind": "attr", + "name": "code", + "value": "409" } ] }, @@ -64061,14 +77371,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "resource-limit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "419" } ], "assertions": [ @@ -64080,6 +77392,11 @@ "kind": "attr", "name": "text", "value": "resource-limit" + }, + { + "kind": "attr", + "name": "code", + "value": "419" } ] }, @@ -64091,14 +77408,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-authorized" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "401" } ], "assertions": [ @@ -64110,6 +77429,11 @@ "kind": "attr", "name": "text", "value": "not-authorized" + }, + { + "kind": "attr", + "name": "code", + "value": "401" } ] }, @@ -64121,14 +77445,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "upgrade-required" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "426" } ], "assertions": [ @@ -64140,6 +77466,11 @@ "kind": "attr", "name": "text", "value": "upgrade-required" + }, + { + "kind": "attr", + "name": "code", + "value": "426" } ] }, @@ -64151,14 +77482,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "already-exists" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "304" } ], "assertions": [ @@ -64170,6 +77503,11 @@ "kind": "attr", "name": "text", "value": "already-exists" + }, + { + "kind": "attr", + "name": "code", + "value": "304" } ] }, @@ -64210,12 +77548,48 @@ { "tag": "JoinLinkedGroupResponseServerError", "moduleName": "WASmaxInGroupsJoinLinkedGroupResponseServerError", - "kind": "error", + "kind": "server_error", + "errorArms": [ + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorServiceUnavailable", + "code": 503, + "text": "service-unavailable" + }, + { + "name": "IQErrorPartialServerError", + "code": 530, + "text": "partial-server-error" + }, + { + "name": "IQErrorFallbackServer", + "codeMin": 500, + "codeMax": 599 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -64228,7 +77602,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -64244,14 +77619,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -64263,6 +77640,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -64274,14 +77656,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "assertions": [ @@ -64293,6 +77677,11 @@ "kind": "attr", "name": "text", "value": "service-unavailable" + }, + { + "kind": "attr", + "name": "code", + "value": "503" } ] }, @@ -64304,14 +77693,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "partial-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "530" } ], "assertions": [ @@ -64323,6 +77714,11 @@ "kind": "attr", "name": "text", "value": "partial-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "530" } ] }, @@ -64432,6 +77828,7 @@ "wireName": "link_type", "type": "string", "required": true, + "literalValue": "sub_group", "sourcePath": [ "links", "link" @@ -64442,7 +77839,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "", @@ -64455,7 +77853,21 @@ "name": "addressingMode", "wireName": "addressing_mode", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_LID_PN", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "lid", + "value": "lid" + }, + { + "name": "pn", + "value": "pn" + } + ] + } } ], "sameNode": true @@ -64488,7 +77900,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "401" } ], "assertions": [ @@ -64511,7 +77924,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "403" } ], "assertions": [ @@ -64534,7 +77948,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "404" } ], "assertions": [ @@ -64557,7 +77972,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "406" } ], "assertions": [ @@ -64580,7 +77996,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "409" } ], "assertions": [ @@ -64603,7 +78020,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "419" } ], "assertions": [ @@ -64626,7 +78044,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "433" } ], "assertions": [ @@ -64649,7 +78068,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -64691,7 +78111,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "403" } ], "repeats": true @@ -64714,6 +78135,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -64727,6 +78162,7 @@ "wireName": "link_type", "type": "string", "required": true, + "literalValue": "sub_group", "sourcePath": [ "links", "link" @@ -64737,7 +78173,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "", @@ -64750,7 +78187,21 @@ "name": "addressingMode", "wireName": "addressing_mode", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_LID_PN", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "lid", + "value": "lid" + }, + { + "name": "pn", + "value": "pn" + } + ] + } } ], "sameNode": true @@ -64783,7 +78234,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "401" } ], "assertions": [ @@ -64806,7 +78258,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "403" } ], "assertions": [ @@ -64829,7 +78282,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "404" } ], "assertions": [ @@ -64852,7 +78306,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "406" } ], "assertions": [ @@ -64875,7 +78330,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "409" } ], "assertions": [ @@ -64898,7 +78354,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "419" } ], "assertions": [ @@ -64921,7 +78378,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "433" } ], "assertions": [ @@ -64944,7 +78402,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -64986,7 +78445,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "403" } ], "repeats": true @@ -65003,12 +78463,78 @@ { "tag": "LinkSubGroupsResponseClientError", "moduleName": "WASmaxInGroupsLinkSubGroupsResponseClientError", - "kind": "error", + "kind": "client_error", + "errorArms": [ + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorNotAuthorized", + "code": 401, + "text": "not-authorized" + }, + { + "name": "IQErrorForbidden", + "code": 403, + "text": "forbidden" + }, + { + "name": "IQErrorItemNotFound", + "code": 404, + "text": "item-not-found" + }, + { + "name": "IQErrorNotAllowed", + "code": 405, + "text": "not-allowed" + }, + { + "name": "IQErrorPayloadTooLarge", + "code": 413, + "text": "payload-too-large" + }, + { + "name": "IQErrorResourceLimit", + "code": 419, + "text": "resource-limit" + }, + { + "name": "IQErrorParentGroupSuspended", + "code": 416, + "text": "parent-group-suspended" + }, + { + "name": "IQErrorGroupHasPendingAddRequests", + "code": 433, + "text": "pending-add-requests" + }, + { + "name": "IQErrorRateOverlimit", + "code": 429, + "text": "rate-overlimit" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -65021,7 +78547,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -65037,14 +78564,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -65056,6 +78585,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -65067,14 +78601,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-authorized" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "401" } ], "assertions": [ @@ -65086,6 +78622,11 @@ "kind": "attr", "name": "text", "value": "not-authorized" + }, + { + "kind": "attr", + "name": "code", + "value": "401" } ] }, @@ -65097,14 +78638,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "forbidden" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "403" } ], "assertions": [ @@ -65116,6 +78659,11 @@ "kind": "attr", "name": "text", "value": "forbidden" + }, + { + "kind": "attr", + "name": "code", + "value": "403" } ] }, @@ -65127,14 +78675,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "item-not-found" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "404" } ], "assertions": [ @@ -65146,6 +78696,11 @@ "kind": "attr", "name": "text", "value": "item-not-found" + }, + { + "kind": "attr", + "name": "code", + "value": "404" } ] }, @@ -65157,14 +78712,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-allowed" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "405" } ], "assertions": [ @@ -65176,6 +78733,11 @@ "kind": "attr", "name": "text", "value": "not-allowed" + }, + { + "kind": "attr", + "name": "code", + "value": "405" } ] }, @@ -65187,14 +78749,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "payload-too-large" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "413" } ], "assertions": [ @@ -65206,6 +78770,11 @@ "kind": "attr", "name": "text", "value": "payload-too-large" + }, + { + "kind": "attr", + "name": "code", + "value": "413" } ] }, @@ -65217,14 +78786,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "resource-limit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "419" } ], "assertions": [ @@ -65236,6 +78807,11 @@ "kind": "attr", "name": "text", "value": "resource-limit" + }, + { + "kind": "attr", + "name": "code", + "value": "419" } ] }, @@ -65247,14 +78823,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "parent-group-suspended" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "416" } ], "assertions": [ @@ -65266,6 +78844,11 @@ "kind": "attr", "name": "text", "value": "parent-group-suspended" + }, + { + "kind": "attr", + "name": "code", + "value": "416" } ] }, @@ -65277,14 +78860,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "pending-add-requests" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "433" } ], "assertions": [ @@ -65296,6 +78881,11 @@ "kind": "attr", "name": "text", "value": "pending-add-requests" + }, + { + "kind": "attr", + "name": "code", + "value": "433" } ] }, @@ -65307,14 +78897,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "rate-overlimit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "429" } ], "assertions": [ @@ -65326,6 +78918,11 @@ "kind": "attr", "name": "text", "value": "rate-overlimit" + }, + { + "kind": "attr", + "name": "code", + "value": "429" } ] } @@ -65339,12 +78936,48 @@ { "tag": "LinkSubGroupsResponseServerError", "moduleName": "WASmaxInGroupsLinkSubGroupsResponseServerError", - "kind": "error", + "kind": "server_error", + "errorArms": [ + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorServiceUnavailable", + "code": 503, + "text": "service-unavailable" + }, + { + "name": "IQErrorPartialServerError", + "code": 530, + "text": "partial-server-error" + }, + { + "name": "IQErrorFallbackServer", + "codeMin": 500, + "codeMax": 599 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -65357,7 +78990,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -65373,14 +79007,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -65392,6 +79028,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -65403,14 +79044,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "assertions": [ @@ -65422,6 +79065,11 @@ "kind": "attr", "name": "text", "value": "service-unavailable" + }, + { + "kind": "attr", + "name": "code", + "value": "503" } ] }, @@ -65433,14 +79081,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "partial-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "530" } ], "assertions": [ @@ -65452,6 +79102,11 @@ "kind": "attr", "name": "text", "value": "partial-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "530" } ] }, @@ -65587,7 +79242,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "", @@ -65600,7 +79256,21 @@ "name": "addressingMode", "wireName": "addressing_mode", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_LID_PN", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "lid", + "value": "lid" + }, + { + "name": "pn", + "value": "pn" + } + ] + } } ], "sameNode": true @@ -65620,10 +79290,10 @@ "tag": "participant", "children": [ { - "method": "attrJidWithType", + "method": "attrJidEnum", "name": "jid", "wireName": "jid", - "type": "jid", + "type": "jid_typed", "required": true }, { @@ -65700,7 +79370,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -65723,7 +79394,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "401" } ], "assertions": [ @@ -65746,7 +79418,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "403" } ], "assertions": [ @@ -65769,7 +79442,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "404" } ], "assertions": [ @@ -65792,7 +79466,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "408" } ], "assertions": [ @@ -65815,7 +79490,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "409" } ], "assertions": [ @@ -65838,7 +79514,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -65861,7 +79538,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "412" } ], "assertions": [ @@ -65902,10 +79580,10 @@ "tag": "participant", "children": [ { - "method": "attrJidWithType", + "method": "attrJidEnum", "name": "jid", "wireName": "jid", - "type": "jid", + "type": "jid_typed", "required": true }, { @@ -65982,7 +79660,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "404" } ], "assertions": [ @@ -66005,7 +79684,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "409" } ], "assertions": [ @@ -66042,10 +79722,24 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", "value": "result" + }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] } ], "fields": [ @@ -66054,7 +79748,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "", @@ -66067,7 +79762,21 @@ "name": "addressingMode", "wireName": "addressing_mode", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_LID_PN", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "lid", + "value": "lid" + }, + { + "name": "pn", + "value": "pn" + } + ] + } } ], "sameNode": true @@ -66087,10 +79796,10 @@ "tag": "participant", "children": [ { - "method": "attrJidWithType", + "method": "attrJidEnum", "name": "jid", "wireName": "jid", - "type": "jid", + "type": "jid_typed", "required": true }, { @@ -66167,7 +79876,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -66190,7 +79900,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "401" } ], "assertions": [ @@ -66213,7 +79924,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "403" } ], "assertions": [ @@ -66236,7 +79948,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "404" } ], "assertions": [ @@ -66259,7 +79972,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "408" } ], "assertions": [ @@ -66282,7 +79996,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "409" } ], "assertions": [ @@ -66305,7 +80020,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -66328,7 +80044,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "412" } ], "assertions": [ @@ -66369,10 +80086,10 @@ "tag": "participant", "children": [ { - "method": "attrJidWithType", + "method": "attrJidEnum", "name": "jid", "wireName": "jid", - "type": "jid", + "type": "jid_typed", "required": true }, { @@ -66449,7 +80166,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "404" } ], "assertions": [ @@ -66472,7 +80190,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "409" } ], "assertions": [ @@ -66503,12 +80222,58 @@ { "tag": "MembershipRequestsActionResponseClientError", "moduleName": "WASmaxInGroupsMembershipRequestsActionResponseClientError", - "kind": "error", + "kind": "client_error", + "errorArms": [ + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorItemNotFound", + "code": 404, + "text": "item-not-found" + }, + { + "name": "IQErrorNotAuthorized", + "code": 401, + "text": "not-authorized" + }, + { + "name": "IQErrorRateOverlimit", + "code": 429, + "text": "rate-overlimit" + }, + { + "name": "IQErrorLocked", + "code": 423, + "text": "locked" + }, + { + "name": "IQErrorFallbackClient", + "codeMin": 400, + "codeMax": 499 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -66521,7 +80286,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -66537,14 +80303,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -66556,6 +80324,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -66567,14 +80340,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "item-not-found" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "404" } ], "assertions": [ @@ -66586,6 +80361,11 @@ "kind": "attr", "name": "text", "value": "item-not-found" + }, + { + "kind": "attr", + "name": "code", + "value": "404" } ] }, @@ -66597,14 +80377,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-authorized" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "401" } ], "assertions": [ @@ -66616,6 +80398,11 @@ "kind": "attr", "name": "text", "value": "not-authorized" + }, + { + "kind": "attr", + "name": "code", + "value": "401" } ] }, @@ -66627,14 +80414,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "rate-overlimit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "429" } ], "assertions": [ @@ -66646,6 +80435,11 @@ "kind": "attr", "name": "text", "value": "rate-overlimit" + }, + { + "kind": "attr", + "name": "code", + "value": "429" } ] }, @@ -66657,14 +80451,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "locked" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "423" } ], "assertions": [ @@ -66676,6 +80472,11 @@ "kind": "attr", "name": "text", "value": "locked" + }, + { + "kind": "attr", + "name": "code", + "value": "423" } ] }, @@ -66716,12 +80517,48 @@ { "tag": "MembershipRequestsActionResponseServerError", "moduleName": "WASmaxInGroupsMembershipRequestsActionResponseServerError", - "kind": "error", + "kind": "server_error", + "errorArms": [ + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorServiceUnavailable", + "code": 503, + "text": "service-unavailable" + }, + { + "name": "IQErrorPartialServerError", + "code": 530, + "text": "partial-server-error" + }, + { + "name": "IQErrorFallbackServer", + "codeMin": 500, + "codeMax": 599 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -66734,7 +80571,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -66750,14 +80588,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -66769,6 +80609,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -66780,14 +80625,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "assertions": [ @@ -66799,6 +80646,11 @@ "kind": "attr", "name": "text", "value": "service-unavailable" + }, + { + "kind": "attr", + "name": "code", + "value": "503" } ] }, @@ -66810,14 +80662,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "partial-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "530" } ], "assertions": [ @@ -66829,6 +80683,11 @@ "kind": "attr", "name": "text", "value": "partial-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "530" } ] }, @@ -66944,7 +80803,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "", @@ -66957,7 +80817,21 @@ "name": "addressingMode", "wireName": "addressing_mode", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_LID_PN", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "lid", + "value": "lid" + }, + { + "name": "pn", + "value": "pn" + } + ] + } } ], "sameNode": true @@ -66981,7 +80855,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": false + "required": false, + "literalValue": "admin" }, { "method": "maybeAttrEnum", @@ -67039,6 +80914,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -67051,7 +80940,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "", @@ -67064,7 +80954,21 @@ "name": "addressingMode", "wireName": "addressing_mode", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_LID_PN", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "lid", + "value": "lid" + }, + { + "name": "pn", + "value": "pn" + } + ] + } } ], "sameNode": true @@ -67088,7 +80992,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": false + "required": false, + "literalValue": "admin" }, { "method": "maybeAttrEnum", @@ -67140,12 +81045,68 @@ { "tag": "PromoteDemoteAdminResponseClientError", "moduleName": "WASmaxInGroupsPromoteDemoteAdminResponseClientError", - "kind": "error", + "kind": "client_error", + "errorArms": [ + { + "name": "IQErrorRateOverlimit", + "code": 429, + "text": "rate-overlimit" + }, + { + "name": "IQErrorBlockedIntegrityEnforcement", + "code": 486, + "text": "blocked-integrity-enforcement" + }, + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorItemNotFound", + "code": 404, + "text": "item-not-found" + }, + { + "name": "IQErrorNotAuthorized", + "code": 401, + "text": "not-authorized" + }, + { + "name": "IQErrorForbidden", + "code": 403, + "text": "forbidden" + }, + { + "name": "IQErrorLocked", + "code": 423, + "text": "locked" + }, + { + "name": "IQErrorFallbackClient", + "codeMin": 400, + "codeMax": 499 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -67158,7 +81119,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -67174,14 +81136,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "rate-overlimit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "429" } ], "assertions": [ @@ -67193,6 +81157,11 @@ "kind": "attr", "name": "text", "value": "rate-overlimit" + }, + { + "kind": "attr", + "name": "code", + "value": "429" } ] }, @@ -67204,14 +81173,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "blocked-integrity-enforcement" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "486" } ], "assertions": [ @@ -67223,6 +81194,11 @@ "kind": "attr", "name": "text", "value": "blocked-integrity-enforcement" + }, + { + "kind": "attr", + "name": "code", + "value": "486" } ] }, @@ -67234,14 +81210,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -67253,6 +81231,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -67264,14 +81247,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "item-not-found" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "404" } ], "assertions": [ @@ -67283,6 +81268,11 @@ "kind": "attr", "name": "text", "value": "item-not-found" + }, + { + "kind": "attr", + "name": "code", + "value": "404" } ] }, @@ -67294,14 +81284,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-authorized" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "401" } ], "assertions": [ @@ -67313,6 +81305,11 @@ "kind": "attr", "name": "text", "value": "not-authorized" + }, + { + "kind": "attr", + "name": "code", + "value": "401" } ] }, @@ -67324,14 +81321,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "forbidden" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "403" } ], "assertions": [ @@ -67343,6 +81342,11 @@ "kind": "attr", "name": "text", "value": "forbidden" + }, + { + "kind": "attr", + "name": "code", + "value": "403" } ] }, @@ -67354,14 +81358,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "locked" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "423" } ], "assertions": [ @@ -67373,6 +81379,11 @@ "kind": "attr", "name": "text", "value": "locked" + }, + { + "kind": "attr", + "name": "code", + "value": "423" } ] }, @@ -67413,12 +81424,48 @@ { "tag": "PromoteDemoteAdminResponseServerError", "moduleName": "WASmaxInGroupsPromoteDemoteAdminResponseServerError", - "kind": "error", + "kind": "server_error", + "errorArms": [ + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorServiceUnavailable", + "code": 503, + "text": "service-unavailable" + }, + { + "name": "IQErrorPartialServerError", + "code": 530, + "text": "partial-server-error" + }, + { + "name": "IQErrorFallbackServer", + "codeMin": 500, + "codeMax": 599 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -67431,7 +81478,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -67447,14 +81495,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -67466,6 +81516,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -67477,14 +81532,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "assertions": [ @@ -67496,6 +81553,11 @@ "kind": "attr", "name": "text", "value": "service-unavailable" + }, + { + "kind": "attr", + "name": "code", + "value": "503" } ] }, @@ -67507,14 +81569,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "partial-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "530" } ], "assertions": [ @@ -67526,6 +81590,11 @@ "kind": "attr", "name": "text", "value": "partial-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "530" } ] }, @@ -67634,7 +81703,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "", @@ -67647,7 +81717,21 @@ "name": "addressingMode", "wireName": "addressing_mode", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_LID_PN", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "lid", + "value": "lid" + }, + { + "name": "pn", + "value": "pn" + } + ] + } } ], "sameNode": true @@ -67671,7 +81755,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": false + "required": false, + "literalValue": "admin" }, { "method": "maybeAttrEnum", @@ -67729,6 +81814,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -67741,7 +81840,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "", @@ -67754,7 +81854,21 @@ "name": "addressingMode", "wireName": "addressing_mode", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_LID_PN", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "lid", + "value": "lid" + }, + { + "name": "pn", + "value": "pn" + } + ] + } } ], "sameNode": true @@ -67778,7 +81892,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": false + "required": false, + "literalValue": "admin" }, { "method": "maybeAttrEnum", @@ -67836,6 +81951,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -67848,7 +81977,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "", @@ -67861,7 +81991,21 @@ "name": "addressingMode", "wireName": "addressing_mode", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_LID_PN", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "lid", + "value": "lid" + }, + { + "name": "pn", + "value": "pn" + } + ] + } } ], "sameNode": true @@ -67930,12 +82074,68 @@ { "tag": "PromoteDemoteResponseClientError", "moduleName": "WASmaxInGroupsPromoteDemoteResponseClientError", - "kind": "error", + "kind": "client_error", + "errorArms": [ + { + "name": "IQErrorRateOverlimit", + "code": 429, + "text": "rate-overlimit" + }, + { + "name": "IQErrorBlockedIntegrityEnforcement", + "code": 486, + "text": "blocked-integrity-enforcement" + }, + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorItemNotFound", + "code": 404, + "text": "item-not-found" + }, + { + "name": "IQErrorNotAuthorized", + "code": 401, + "text": "not-authorized" + }, + { + "name": "IQErrorForbidden", + "code": 403, + "text": "forbidden" + }, + { + "name": "IQErrorLocked", + "code": 423, + "text": "locked" + }, + { + "name": "IQErrorFallbackClient", + "codeMin": 400, + "codeMax": 499 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -67948,7 +82148,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -67964,14 +82165,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "rate-overlimit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "429" } ], "assertions": [ @@ -67983,6 +82186,11 @@ "kind": "attr", "name": "text", "value": "rate-overlimit" + }, + { + "kind": "attr", + "name": "code", + "value": "429" } ] }, @@ -67994,14 +82202,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "blocked-integrity-enforcement" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "486" } ], "assertions": [ @@ -68013,6 +82223,11 @@ "kind": "attr", "name": "text", "value": "blocked-integrity-enforcement" + }, + { + "kind": "attr", + "name": "code", + "value": "486" } ] }, @@ -68024,14 +82239,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -68043,6 +82260,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -68054,14 +82276,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "item-not-found" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "404" } ], "assertions": [ @@ -68073,6 +82297,11 @@ "kind": "attr", "name": "text", "value": "item-not-found" + }, + { + "kind": "attr", + "name": "code", + "value": "404" } ] }, @@ -68084,14 +82313,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-authorized" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "401" } ], "assertions": [ @@ -68103,6 +82334,11 @@ "kind": "attr", "name": "text", "value": "not-authorized" + }, + { + "kind": "attr", + "name": "code", + "value": "401" } ] }, @@ -68114,14 +82350,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "forbidden" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "403" } ], "assertions": [ @@ -68133,6 +82371,11 @@ "kind": "attr", "name": "text", "value": "forbidden" + }, + { + "kind": "attr", + "name": "code", + "value": "403" } ] }, @@ -68144,14 +82387,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "locked" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "423" } ], "assertions": [ @@ -68163,6 +82408,11 @@ "kind": "attr", "name": "text", "value": "locked" + }, + { + "kind": "attr", + "name": "code", + "value": "423" } ] }, @@ -68203,12 +82453,48 @@ { "tag": "PromoteDemoteResponseServerError", "moduleName": "WASmaxInGroupsPromoteDemoteResponseServerError", - "kind": "error", + "kind": "server_error", + "errorArms": [ + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorServiceUnavailable", + "code": 503, + "text": "service-unavailable" + }, + { + "name": "IQErrorPartialServerError", + "code": 530, + "text": "partial-server-error" + }, + { + "name": "IQErrorFallbackServer", + "codeMin": 500, + "codeMax": 599 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -68221,7 +82507,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -68237,14 +82524,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -68256,6 +82545,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -68267,14 +82561,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "assertions": [ @@ -68286,6 +82582,11 @@ "kind": "attr", "name": "text", "value": "service-unavailable" + }, + { + "kind": "attr", + "name": "code", + "value": "503" } ] }, @@ -68297,14 +82598,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "partial-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "530" } ], "assertions": [ @@ -68316,6 +82619,11 @@ "kind": "attr", "name": "text", "value": "partial-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "530" } ] }, @@ -68408,7 +82716,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "maybeAttrString", @@ -68416,6 +82725,7 @@ "wireName": "linked_groups", "type": "string", "required": false, + "literalValue": "true", "sourcePath": [ "remove" ] @@ -68431,7 +82741,21 @@ "name": "addressingMode", "wireName": "addressing_mode", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_LID_PN", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "lid", + "value": "lid" + }, + { + "name": "pn", + "value": "pn" + } + ] + } } ], "sameNode": true @@ -68444,10 +82768,10 @@ "tag": "participant", "children": [ { - "method": "attrJidWithType", + "method": "attrJidEnum", "name": "jid", "wireName": "jid", - "type": "jid", + "type": "jid_typed", "required": true }, { @@ -68496,7 +82820,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "404" } ], "assertions": [ @@ -68519,7 +82844,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "405" } ], "assertions": [ @@ -68542,7 +82868,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "406" } ], "assertions": [ @@ -68565,7 +82892,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -68599,10 +82927,24 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", "value": "result" + }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] } ], "fields": [ @@ -68611,7 +82953,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "maybeAttrString", @@ -68619,6 +82962,7 @@ "wireName": "linked_groups", "type": "string", "required": false, + "literalValue": "true", "sourcePath": [ "remove" ] @@ -68634,7 +82978,21 @@ "name": "addressingMode", "wireName": "addressing_mode", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_LID_PN", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "lid", + "value": "lid" + }, + { + "name": "pn", + "value": "pn" + } + ] + } } ], "sameNode": true @@ -68647,10 +83005,10 @@ "tag": "participant", "children": [ { - "method": "attrJidWithType", + "method": "attrJidEnum", "name": "jid", "wireName": "jid", - "type": "jid", + "type": "jid_typed", "required": true }, { @@ -68699,7 +83057,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "404" } ], "assertions": [ @@ -68722,7 +83081,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "405" } ], "assertions": [ @@ -68745,7 +83105,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "406" } ], "assertions": [ @@ -68768,7 +83129,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -68796,12 +83158,68 @@ { "tag": "RemoveParticipantsResponseClientError", "moduleName": "WASmaxInGroupsRemoveParticipantsResponseClientError", - "kind": "error", + "kind": "client_error", + "errorArms": [ + { + "name": "IQErrorRateOverlimit", + "code": 429, + "text": "rate-overlimit" + }, + { + "name": "IQErrorPayloadTooLarge", + "code": 413, + "text": "payload-too-large" + }, + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorItemNotFound", + "code": 404, + "text": "item-not-found" + }, + { + "name": "IQErrorNotAuthorized", + "code": 401, + "text": "not-authorized" + }, + { + "name": "IQErrorForbidden", + "code": 403, + "text": "forbidden" + }, + { + "name": "IQErrorLocked", + "code": 423, + "text": "locked" + }, + { + "name": "IQErrorFallbackClient", + "codeMin": 400, + "codeMax": 499 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -68814,7 +83232,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -68830,14 +83249,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "rate-overlimit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "429" } ], "assertions": [ @@ -68849,6 +83270,11 @@ "kind": "attr", "name": "text", "value": "rate-overlimit" + }, + { + "kind": "attr", + "name": "code", + "value": "429" } ] }, @@ -68860,14 +83286,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "payload-too-large" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "413" } ], "assertions": [ @@ -68879,6 +83307,11 @@ "kind": "attr", "name": "text", "value": "payload-too-large" + }, + { + "kind": "attr", + "name": "code", + "value": "413" } ] }, @@ -68890,14 +83323,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -68909,6 +83344,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -68920,14 +83360,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "item-not-found" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "404" } ], "assertions": [ @@ -68939,6 +83381,11 @@ "kind": "attr", "name": "text", "value": "item-not-found" + }, + { + "kind": "attr", + "name": "code", + "value": "404" } ] }, @@ -68950,14 +83397,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-authorized" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "401" } ], "assertions": [ @@ -68969,6 +83418,11 @@ "kind": "attr", "name": "text", "value": "not-authorized" + }, + { + "kind": "attr", + "name": "code", + "value": "401" } ] }, @@ -68980,14 +83434,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "forbidden" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "403" } ], "assertions": [ @@ -68999,6 +83455,11 @@ "kind": "attr", "name": "text", "value": "forbidden" + }, + { + "kind": "attr", + "name": "code", + "value": "403" } ] }, @@ -69010,14 +83471,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "locked" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "423" } ], "assertions": [ @@ -69029,6 +83492,11 @@ "kind": "attr", "name": "text", "value": "locked" + }, + { + "kind": "attr", + "name": "code", + "value": "423" } ] }, @@ -69069,12 +83537,48 @@ { "tag": "RemoveParticipantsResponseServerError", "moduleName": "WASmaxInGroupsRemoveParticipantsResponseServerError", - "kind": "error", + "kind": "server_error", + "errorArms": [ + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorServiceUnavailable", + "code": 503, + "text": "service-unavailable" + }, + { + "name": "IQErrorPartialServerError", + "code": 530, + "text": "partial-server-error" + }, + { + "name": "IQErrorFallbackServer", + "codeMin": 500, + "codeMax": 599 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -69087,7 +83591,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -69103,14 +83608,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -69122,6 +83629,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -69133,14 +83645,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "assertions": [ @@ -69152,6 +83666,11 @@ "kind": "attr", "name": "text", "value": "service-unavailable" + }, + { + "kind": "attr", + "name": "code", + "value": "503" } ] }, @@ -69163,14 +83682,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "partial-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "530" } ], "assertions": [ @@ -69182,6 +83703,11 @@ "kind": "attr", "name": "text", "value": "partial-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "530" } ] }, @@ -69267,7 +83793,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ], "variants": [ @@ -69280,6 +83807,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -69292,19 +83833,61 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ] }, { "tag": "ReportMessagesResponseClientError", "moduleName": "WASmaxInGroupsReportMessagesResponseClientError", - "kind": "error", + "kind": "client_error", + "errorArms": [ + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorForbidden", + "code": 403, + "text": "forbidden" + }, + { + "name": "IQErrorItemNotFound", + "code": 404, + "text": "item-not-found" + }, + { + "name": "IQErrorRateOverlimit", + "code": 429, + "text": "rate-overlimit" + }, + { + "name": "IQErrorLocked", + "code": 423, + "text": "locked" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -69317,7 +83900,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -69333,14 +83917,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -69352,6 +83938,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -69363,14 +83954,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "forbidden" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "403" } ], "assertions": [ @@ -69382,6 +83975,11 @@ "kind": "attr", "name": "text", "value": "forbidden" + }, + { + "kind": "attr", + "name": "code", + "value": "403" } ] }, @@ -69393,14 +83991,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "item-not-found" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "404" } ], "assertions": [ @@ -69412,6 +84012,11 @@ "kind": "attr", "name": "text", "value": "item-not-found" + }, + { + "kind": "attr", + "name": "code", + "value": "404" } ] }, @@ -69423,14 +84028,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "rate-overlimit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "429" } ], "assertions": [ @@ -69442,6 +84049,11 @@ "kind": "attr", "name": "text", "value": "rate-overlimit" + }, + { + "kind": "attr", + "name": "code", + "value": "429" } ] }, @@ -69453,14 +84065,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "locked" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "423" } ], "assertions": [ @@ -69472,6 +84086,11 @@ "kind": "attr", "name": "text", "value": "locked" + }, + { + "kind": "attr", + "name": "code", + "value": "423" } ] } @@ -69485,12 +84104,48 @@ { "tag": "ReportMessagesResponseServerError", "moduleName": "WASmaxInGroupsReportMessagesResponseServerError", - "kind": "error", + "kind": "server_error", + "errorArms": [ + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorServiceUnavailable", + "code": 503, + "text": "service-unavailable" + }, + { + "name": "IQErrorPartialServerError", + "code": 530, + "text": "partial-server-error" + }, + { + "name": "IQErrorFallbackServer", + "codeMin": 500, + "codeMax": 599 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -69503,7 +84158,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -69519,14 +84175,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -69538,6 +84196,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -69549,14 +84212,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "assertions": [ @@ -69568,6 +84233,11 @@ "kind": "attr", "name": "text", "value": "service-unavailable" + }, + { + "kind": "attr", + "name": "code", + "value": "503" } ] }, @@ -69579,14 +84249,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "partial-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "530" } ], "assertions": [ @@ -69598,6 +84270,11 @@ "kind": "attr", "name": "text", "value": "partial-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "530" } ] }, @@ -69684,7 +84361,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "", @@ -69697,7 +84375,21 @@ "name": "addressingMode", "wireName": "addressing_mode", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_LID_PN", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "lid", + "value": "lid" + }, + { + "name": "pn", + "value": "pn" + } + ] + } } ], "sameNode": true @@ -69721,7 +84413,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": false + "required": false, + "literalValue": "404" }, { "method": "", @@ -69772,6 +84465,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -69784,7 +84491,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "", @@ -69797,7 +84505,21 @@ "name": "addressingMode", "wireName": "addressing_mode", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_LID_PN", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "lid", + "value": "lid" + }, + { + "name": "pn", + "value": "pn" + } + ] + } } ], "sameNode": true @@ -69821,7 +84543,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": false + "required": false, + "literalValue": "404" }, { "method": "", @@ -69866,12 +84589,58 @@ { "tag": "RevokeRequestCodeResponseClientError", "moduleName": "WASmaxInGroupsRevokeRequestCodeResponseClientError", - "kind": "error", + "kind": "client_error", + "errorArms": [ + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorItemNotFound", + "code": 404, + "text": "item-not-found" + }, + { + "name": "IQErrorNotAuthorized", + "code": 401, + "text": "not-authorized" + }, + { + "name": "IQErrorForbidden", + "code": 403, + "text": "forbidden" + }, + { + "name": "IQErrorLocked", + "code": 423, + "text": "locked" + }, + { + "name": "IQErrorFallbackClient", + "codeMin": 400, + "codeMax": 499 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -69884,7 +84653,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -69900,14 +84670,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -69919,6 +84691,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -69930,14 +84707,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "item-not-found" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "404" } ], "assertions": [ @@ -69949,6 +84728,11 @@ "kind": "attr", "name": "text", "value": "item-not-found" + }, + { + "kind": "attr", + "name": "code", + "value": "404" } ] }, @@ -69960,14 +84744,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-authorized" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "401" } ], "assertions": [ @@ -69979,6 +84765,11 @@ "kind": "attr", "name": "text", "value": "not-authorized" + }, + { + "kind": "attr", + "name": "code", + "value": "401" } ] }, @@ -69990,14 +84781,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "forbidden" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "403" } ], "assertions": [ @@ -70009,6 +84802,11 @@ "kind": "attr", "name": "text", "value": "forbidden" + }, + { + "kind": "attr", + "name": "code", + "value": "403" } ] }, @@ -70020,14 +84818,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "locked" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "423" } ], "assertions": [ @@ -70039,6 +84839,11 @@ "kind": "attr", "name": "text", "value": "locked" + }, + { + "kind": "attr", + "name": "code", + "value": "423" } ] }, @@ -70079,12 +84884,48 @@ { "tag": "RevokeRequestCodeResponseServerError", "moduleName": "WASmaxInGroupsRevokeRequestCodeResponseServerError", - "kind": "error", + "kind": "server_error", + "errorArms": [ + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorServiceUnavailable", + "code": 503, + "text": "service-unavailable" + }, + { + "name": "IQErrorPartialServerError", + "code": 530, + "text": "partial-server-error" + }, + { + "name": "IQErrorFallbackServer", + "codeMin": 500, + "codeMax": 599 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -70097,7 +84938,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -70113,14 +84955,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -70132,6 +84976,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -70143,14 +84992,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "assertions": [ @@ -70162,6 +85013,11 @@ "kind": "attr", "name": "text", "value": "service-unavailable" + }, + { + "kind": "attr", + "name": "code", + "value": "503" } ] }, @@ -70173,14 +85029,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "partial-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "530" } ], "assertions": [ @@ -70192,6 +85050,11 @@ "kind": "attr", "name": "text", "value": "partial-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "530" } ] }, @@ -70295,7 +85158,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ], "variants": [ @@ -70308,6 +85172,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -70327,19 +85205,76 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ] }, { "tag": "SetDescriptionResponseClientError", "moduleName": "WASmaxInGroupsSetDescriptionResponseClientError", - "kind": "error", + "kind": "client_error", + "errorArms": [ + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorConflict", + "code": 409, + "text": "conflict" + }, + { + "name": "IQErrorItemNotFound", + "code": 404, + "text": "item-not-found" + }, + { + "name": "IQErrorNotAuthorized", + "code": 401, + "text": "not-authorized" + }, + { + "name": "IQErrorForbidden", + "code": 403, + "text": "forbidden" + }, + { + "name": "IQErrorNotAcceptable", + "code": 406, + "text": "not-acceptable" + }, + { + "name": "IQErrorLocked", + "code": 423, + "text": "locked" + }, + { + "name": "IQErrorFallbackClient", + "codeMin": 400, + "codeMax": 499 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -70352,7 +85287,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -70368,14 +85304,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -70387,6 +85325,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -70398,14 +85341,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "conflict" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "409" } ], "assertions": [ @@ -70417,6 +85362,11 @@ "kind": "attr", "name": "text", "value": "conflict" + }, + { + "kind": "attr", + "name": "code", + "value": "409" } ] }, @@ -70428,14 +85378,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "item-not-found" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "404" } ], "assertions": [ @@ -70447,6 +85399,11 @@ "kind": "attr", "name": "text", "value": "item-not-found" + }, + { + "kind": "attr", + "name": "code", + "value": "404" } ] }, @@ -70458,14 +85415,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-authorized" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "401" } ], "assertions": [ @@ -70477,6 +85436,11 @@ "kind": "attr", "name": "text", "value": "not-authorized" + }, + { + "kind": "attr", + "name": "code", + "value": "401" } ] }, @@ -70488,14 +85452,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "forbidden" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "403" } ], "assertions": [ @@ -70507,6 +85473,11 @@ "kind": "attr", "name": "text", "value": "forbidden" + }, + { + "kind": "attr", + "name": "code", + "value": "403" } ] }, @@ -70518,14 +85489,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-acceptable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "406" }, { "method": "child", @@ -70561,6 +85534,11 @@ "kind": "attr", "name": "text", "value": "not-acceptable" + }, + { + "kind": "attr", + "name": "code", + "value": "406" } ] }, @@ -70572,14 +85550,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "locked" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "423" } ], "assertions": [ @@ -70591,6 +85571,11 @@ "kind": "attr", "name": "text", "value": "locked" + }, + { + "kind": "attr", + "name": "code", + "value": "423" } ] }, @@ -70631,12 +85616,48 @@ { "tag": "SetDescriptionResponseServerError", "moduleName": "WASmaxInGroupsSetDescriptionResponseServerError", - "kind": "error", + "kind": "server_error", + "errorArms": [ + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorServiceUnavailable", + "code": 503, + "text": "service-unavailable" + }, + { + "name": "IQErrorPartialServerError", + "code": 530, + "text": "partial-server-error" + }, + { + "name": "IQErrorFallbackServer", + "codeMin": 500, + "codeMax": 599 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -70649,7 +85670,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -70665,14 +85687,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -70684,6 +85708,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -70695,14 +85724,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "assertions": [ @@ -70714,6 +85745,11 @@ "kind": "attr", "name": "text", "value": "service-unavailable" + }, + { + "kind": "attr", + "name": "code", + "value": "503" } ] }, @@ -70725,14 +85761,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "partial-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "530" } ], "assertions": [ @@ -70744,6 +85782,11 @@ "kind": "attr", "name": "text", "value": "partial-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "530" } ] }, @@ -70932,7 +85975,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "", @@ -71031,7 +86075,8 @@ "name": "state", "wireName": "state", "type": "string", - "required": true + "required": true, + "literalValue": "on" } ], "assertions": [ @@ -71054,7 +86099,8 @@ "name": "state", "wireName": "state", "type": "string", - "required": true + "required": true, + "literalValue": "off" } ], "assertions": [ @@ -71127,6 +86173,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -71139,7 +86199,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "", @@ -71238,7 +86299,8 @@ "name": "state", "wireName": "state", "type": "string", - "required": true + "required": true, + "literalValue": "on" } ], "assertions": [ @@ -71261,7 +86323,8 @@ "name": "state", "wireName": "state", "type": "string", - "required": true + "required": true, + "literalValue": "off" } ], "assertions": [ @@ -71328,12 +86391,78 @@ { "tag": "SetPropertyResponseClientError", "moduleName": "WASmaxInGroupsSetPropertyResponseClientError", - "kind": "error", + "kind": "client_error", + "errorArms": [ + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorNotAuthorized", + "code": 401, + "text": "not-authorized" + }, + { + "name": "IQErrorForbidden", + "code": 403, + "text": "forbidden" + }, + { + "name": "IQErrorItemNotFound", + "code": 404, + "text": "item-not-found" + }, + { + "name": "IQErrorNotAllowed", + "code": 405, + "text": "not-allowed" + }, + { + "name": "IQErrorResourceLimit", + "code": 419, + "text": "resource-limit" + }, + { + "name": "IQErrorLocked", + "code": 423, + "text": "locked" + }, + { + "name": "IQErrorRateOverlimit", + "code": 429, + "text": "rate-overlimit" + }, + { + "name": "IQErrorUpgradeRequired", + "code": 426, + "text": "upgrade-required" + }, + { + "name": "IQErrorFallbackClient", + "codeMin": 400, + "codeMax": 499 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -71346,7 +86475,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -71362,14 +86492,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -71381,6 +86513,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -71392,14 +86529,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-authorized" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "401" } ], "assertions": [ @@ -71411,6 +86550,11 @@ "kind": "attr", "name": "text", "value": "not-authorized" + }, + { + "kind": "attr", + "name": "code", + "value": "401" } ] }, @@ -71422,14 +86566,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "forbidden" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "403" } ], "assertions": [ @@ -71441,6 +86587,11 @@ "kind": "attr", "name": "text", "value": "forbidden" + }, + { + "kind": "attr", + "name": "code", + "value": "403" } ] }, @@ -71452,14 +86603,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "item-not-found" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "404" } ], "assertions": [ @@ -71471,6 +86624,11 @@ "kind": "attr", "name": "text", "value": "item-not-found" + }, + { + "kind": "attr", + "name": "code", + "value": "404" } ] }, @@ -71482,14 +86640,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-allowed" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "405" } ], "assertions": [ @@ -71501,6 +86661,11 @@ "kind": "attr", "name": "text", "value": "not-allowed" + }, + { + "kind": "attr", + "name": "code", + "value": "405" } ] }, @@ -71512,14 +86677,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "resource-limit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "419" } ], "assertions": [ @@ -71531,6 +86698,11 @@ "kind": "attr", "name": "text", "value": "resource-limit" + }, + { + "kind": "attr", + "name": "code", + "value": "419" } ] }, @@ -71542,14 +86714,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "locked" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "423" } ], "assertions": [ @@ -71561,6 +86735,11 @@ "kind": "attr", "name": "text", "value": "locked" + }, + { + "kind": "attr", + "name": "code", + "value": "423" } ] }, @@ -71572,14 +86751,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "rate-overlimit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "429" } ], "assertions": [ @@ -71591,6 +86772,11 @@ "kind": "attr", "name": "text", "value": "rate-overlimit" + }, + { + "kind": "attr", + "name": "code", + "value": "429" } ] }, @@ -71602,14 +86788,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "upgrade-required" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "426" } ], "assertions": [ @@ -71621,6 +86809,11 @@ "kind": "attr", "name": "text", "value": "upgrade-required" + }, + { + "kind": "attr", + "name": "code", + "value": "426" } ] }, @@ -71661,12 +86854,48 @@ { "tag": "SetPropertyResponseServerError", "moduleName": "WASmaxInGroupsSetPropertyResponseServerError", - "kind": "error", + "kind": "server_error", + "errorArms": [ + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorServiceUnavailable", + "code": 503, + "text": "service-unavailable" + }, + { + "name": "IQErrorPartialServerError", + "code": 530, + "text": "partial-server-error" + }, + { + "name": "IQErrorFallbackServer", + "codeMin": 500, + "codeMax": 599 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -71679,7 +86908,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -71695,14 +86925,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -71714,6 +86946,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -71725,14 +86962,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "assertions": [ @@ -71744,6 +86983,11 @@ "kind": "attr", "name": "text", "value": "service-unavailable" + }, + { + "kind": "attr", + "name": "code", + "value": "503" } ] }, @@ -71755,14 +86999,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "partial-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "530" } ], "assertions": [ @@ -71774,6 +87020,11 @@ "kind": "attr", "name": "text", "value": "partial-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "530" } ] }, @@ -71846,7 +87097,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ], "variants": [ @@ -71859,6 +87111,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -71871,19 +87137,76 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ] }, { "tag": "SetSubjectResponseClientError", "moduleName": "WASmaxInGroupsSetSubjectResponseClientError", - "kind": "error", + "kind": "client_error", + "errorArms": [ + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorItemNotFound", + "code": 404, + "text": "item-not-found" + }, + { + "name": "IQErrorNotAuthorized", + "code": 401, + "text": "not-authorized" + }, + { + "name": "IQErrorForbidden", + "code": 403, + "text": "forbidden" + }, + { + "name": "IQErrorNotAcceptable", + "code": 406, + "text": "not-acceptable" + }, + { + "name": "IQErrorLocked", + "code": 423, + "text": "locked" + }, + { + "name": "IQErrorRateOverlimit", + "code": 429, + "text": "rate-overlimit" + }, + { + "name": "IQErrorFallbackClient", + "codeMin": 400, + "codeMax": 499 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -71896,7 +87219,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -71912,14 +87236,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -71931,6 +87257,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -71942,14 +87273,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "item-not-found" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "404" } ], "assertions": [ @@ -71961,6 +87294,11 @@ "kind": "attr", "name": "text", "value": "item-not-found" + }, + { + "kind": "attr", + "name": "code", + "value": "404" } ] }, @@ -71972,14 +87310,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-authorized" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "401" } ], "assertions": [ @@ -71991,6 +87331,11 @@ "kind": "attr", "name": "text", "value": "not-authorized" + }, + { + "kind": "attr", + "name": "code", + "value": "401" } ] }, @@ -72002,14 +87347,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "forbidden" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "403" } ], "assertions": [ @@ -72021,6 +87368,11 @@ "kind": "attr", "name": "text", "value": "forbidden" + }, + { + "kind": "attr", + "name": "code", + "value": "403" } ] }, @@ -72032,14 +87384,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-acceptable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "406" }, { "method": "child", @@ -72075,6 +87429,11 @@ "kind": "attr", "name": "text", "value": "not-acceptable" + }, + { + "kind": "attr", + "name": "code", + "value": "406" } ] }, @@ -72086,14 +87445,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "locked" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "423" } ], "assertions": [ @@ -72105,6 +87466,11 @@ "kind": "attr", "name": "text", "value": "locked" + }, + { + "kind": "attr", + "name": "code", + "value": "423" } ] }, @@ -72116,14 +87482,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "rate-overlimit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "429" } ], "assertions": [ @@ -72135,6 +87503,11 @@ "kind": "attr", "name": "text", "value": "rate-overlimit" + }, + { + "kind": "attr", + "name": "code", + "value": "429" } ] }, @@ -72175,12 +87548,48 @@ { "tag": "SetSubjectResponseServerError", "moduleName": "WASmaxInGroupsSetSubjectResponseServerError", - "kind": "error", + "kind": "server_error", + "errorArms": [ + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorServiceUnavailable", + "code": 503, + "text": "service-unavailable" + }, + { + "name": "IQErrorPartialServerError", + "code": 530, + "text": "partial-server-error" + }, + { + "name": "IQErrorFallbackServer", + "codeMin": 500, + "codeMax": 599 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -72193,7 +87602,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -72209,14 +87619,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -72228,6 +87640,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -72239,14 +87656,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "assertions": [ @@ -72258,6 +87677,11 @@ "kind": "attr", "name": "text", "value": "service-unavailable" + }, + { + "kind": "attr", + "name": "code", + "value": "503" } ] }, @@ -72269,14 +87693,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "partial-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "530" } ], "assertions": [ @@ -72288,6 +87714,11 @@ "kind": "attr", "name": "text", "value": "partial-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "530" } ] }, @@ -72406,7 +87837,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "", @@ -72419,7 +87851,21 @@ "name": "addressingMode", "wireName": "addressing_mode", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_LID_PN", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "lid", + "value": "lid" + }, + { + "name": "pn", + "value": "pn" + } + ] + } } ], "sameNode": true @@ -72482,7 +87928,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "404" } ], "assertions": [ @@ -72505,7 +87952,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "409" } ], "assertions": [ @@ -72528,7 +87976,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "419" } ], "assertions": [ @@ -72551,7 +88000,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "433" } ], "assertions": [ @@ -72574,7 +88024,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -72655,7 +88106,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "404" } ], "sameNode": true @@ -72761,7 +88213,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "404" } ], "sameNode": true @@ -72846,6 +88299,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -72858,7 +88325,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "", @@ -72871,7 +88339,21 @@ "name": "addressingMode", "wireName": "addressing_mode", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_LID_PN", + "module": "WASmaxInGroupsEnums", + "variants": [ + { + "name": "lid", + "value": "lid" + }, + { + "name": "pn", + "value": "pn" + } + ] + } } ], "sameNode": true @@ -72934,7 +88416,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "404" } ], "assertions": [ @@ -72957,7 +88440,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "409" } ], "assertions": [ @@ -72980,7 +88464,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "419" } ], "assertions": [ @@ -73003,7 +88488,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "433" } ], "assertions": [ @@ -73026,7 +88512,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -73107,7 +88594,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "404" } ], "sameNode": true @@ -73213,7 +88701,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "404" } ], "sameNode": true @@ -73292,12 +88781,53 @@ { "tag": "SubGroupSuggestionsActionResponseClientError", "moduleName": "WASmaxInGroupsSubGroupSuggestionsActionResponseClientError", - "kind": "error", + "kind": "client_error", + "errorArms": [ + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorItemNotFound", + "code": 404, + "text": "item-not-found" + }, + { + "name": "IQErrorNotAuthorized", + "code": 401, + "text": "not-authorized" + }, + { + "name": "IQErrorRateOverlimit", + "code": 429, + "text": "rate-overlimit" + }, + { + "name": "IQErrorFallbackClient", + "codeMin": 400, + "codeMax": 499 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -73310,7 +88840,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -73326,14 +88857,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -73345,6 +88878,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -73356,14 +88894,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "item-not-found" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "404" } ], "assertions": [ @@ -73375,6 +88915,11 @@ "kind": "attr", "name": "text", "value": "item-not-found" + }, + { + "kind": "attr", + "name": "code", + "value": "404" } ] }, @@ -73386,14 +88931,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-authorized" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "401" } ], "assertions": [ @@ -73405,6 +88952,11 @@ "kind": "attr", "name": "text", "value": "not-authorized" + }, + { + "kind": "attr", + "name": "code", + "value": "401" } ] }, @@ -73416,14 +88968,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "rate-overlimit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "429" } ], "assertions": [ @@ -73435,6 +88989,11 @@ "kind": "attr", "name": "text", "value": "rate-overlimit" + }, + { + "kind": "attr", + "name": "code", + "value": "429" } ] }, @@ -73475,12 +89034,48 @@ { "tag": "SubGroupSuggestionsActionResponseServerError", "moduleName": "WASmaxInGroupsSubGroupSuggestionsActionResponseServerError", - "kind": "error", + "kind": "server_error", + "errorArms": [ + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorServiceUnavailable", + "code": 503, + "text": "service-unavailable" + }, + { + "name": "IQErrorPartialServerError", + "code": 530, + "text": "partial-server-error" + }, + { + "name": "IQErrorFallbackServer", + "codeMin": 500, + "codeMax": 599 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -73493,7 +89088,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -73509,14 +89105,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -73528,6 +89126,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -73539,14 +89142,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "assertions": [ @@ -73558,6 +89163,11 @@ "kind": "attr", "name": "text", "value": "service-unavailable" + }, + { + "kind": "attr", + "name": "code", + "value": "503" } ] }, @@ -73569,14 +89179,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "partial-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "530" } ], "assertions": [ @@ -73588,6 +89200,11 @@ "kind": "attr", "name": "text", "value": "partial-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "530" } ] }, @@ -73687,6 +89304,7 @@ "wireName": "unlink_type", "type": "string", "required": true, + "literalValue": "sub_group", "sourcePath": [ "unlink" ] @@ -73696,7 +89314,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "child", @@ -73717,7 +89336,8 @@ "name": "removeOrphanedMembers", "wireName": "remove_orphaned_members", "type": "string", - "required": false + "required": false, + "literalValue": "true" }, { "method": "", @@ -73733,7 +89353,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -73756,7 +89377,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "401" } ], "assertions": [ @@ -73779,7 +89401,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "404" } ], "assertions": [ @@ -73802,7 +89425,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "406" } ], "assertions": [ @@ -73825,7 +89449,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "530" } ], "assertions": [ @@ -73848,7 +89473,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -73882,6 +89508,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -73895,6 +89535,7 @@ "wireName": "unlink_type", "type": "string", "required": true, + "literalValue": "sub_group", "sourcePath": [ "unlink" ] @@ -73904,7 +89545,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "child", @@ -73925,7 +89567,8 @@ "name": "removeOrphanedMembers", "wireName": "remove_orphaned_members", "type": "string", - "required": false + "required": false, + "literalValue": "true" }, { "method": "", @@ -73941,7 +89584,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -73964,7 +89608,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "401" } ], "assertions": [ @@ -73987,7 +89632,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "404" } ], "assertions": [ @@ -74010,7 +89656,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "406" } ], "assertions": [ @@ -74033,7 +89680,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "530" } ], "assertions": [ @@ -74056,7 +89704,8 @@ "name": "error", "wireName": "error", "type": "string", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -74084,12 +89733,48 @@ { "tag": "UnlinkGroupsResponseClientError", "moduleName": "WASmaxInGroupsUnlinkGroupsResponseClientError", - "kind": "error", + "kind": "client_error", + "errorArms": [ + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorNotAuthorized", + "code": 401, + "text": "not-authorized" + }, + { + "name": "IQErrorItemNotFound", + "code": 404, + "text": "item-not-found" + }, + { + "name": "IQErrorNotAcceptable", + "code": 406, + "text": "not-acceptable" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -74102,7 +89787,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -74118,14 +89804,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -74137,6 +89825,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -74148,14 +89841,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-authorized" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "401" } ], "assertions": [ @@ -74167,6 +89862,11 @@ "kind": "attr", "name": "text", "value": "not-authorized" + }, + { + "kind": "attr", + "name": "code", + "value": "401" } ] }, @@ -74178,14 +89878,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "item-not-found" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "404" } ], "assertions": [ @@ -74197,6 +89899,11 @@ "kind": "attr", "name": "text", "value": "item-not-found" + }, + { + "kind": "attr", + "name": "code", + "value": "404" } ] }, @@ -74208,14 +89915,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-acceptable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "406" }, { "method": "child", @@ -74251,6 +89960,11 @@ "kind": "attr", "name": "text", "value": "not-acceptable" + }, + { + "kind": "attr", + "name": "code", + "value": "406" } ] } @@ -74264,12 +89978,48 @@ { "tag": "UnlinkGroupsResponseServerError", "moduleName": "WASmaxInGroupsUnlinkGroupsResponseServerError", - "kind": "error", + "kind": "server_error", + "errorArms": [ + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorServiceUnavailable", + "code": 503, + "text": "service-unavailable" + }, + { + "name": "IQErrorPartialServerError", + "code": 530, + "text": "partial-server-error" + }, + { + "name": "IQErrorFallbackServer", + "codeMin": 500, + "codeMax": 599 + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -74282,7 +90032,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -74298,14 +90049,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -74317,6 +90070,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -74328,14 +90086,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "assertions": [ @@ -74347,6 +90107,11 @@ "kind": "attr", "name": "text", "value": "service-unavailable" + }, + { + "kind": "attr", + "name": "code", + "value": "503" } ] }, @@ -74358,14 +90123,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "partial-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "530" } ], "assertions": [ @@ -74377,6 +90144,11 @@ "kind": "attr", "name": "text", "value": "partial-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "530" } ] }, @@ -74556,6 +90328,18 @@ "type": "string", "required": true }, + { + "method": "attrFutureTime", + "name": "auth_ttl", + "type": "integer", + "required": true + }, + { + "method": "attrFutureTime", + "name": "ttl", + "type": "integer", + "required": true + }, { "method": "attrInt", "name": "max_buckets", @@ -74657,14 +90441,21 @@ "kind": "attr", "name": "type", "value": "result" + }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] } ], "fields": [ { - "method": "attrJidWithType", + "method": "attrJidEnum", "name": "from", "wireName": "from", - "type": "jid", + "type": "jid_typed", "required": true }, { @@ -74672,7 +90463,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "attrInt", @@ -74764,14 +90556,29 @@ "name": "type", "wireName": "type", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_PAYONDELIVERY_PIXKEY", + "module": "WASmaxInBrPaymentEnums", + "variants": [ + { + "name": "pay_on_delivery", + "value": "pay_on_delivery" + }, + { + "name": "pix_key", + "value": "pix_key" + } + ] + } }, { "method": "maybeAttrString", "name": "country", "wireName": "country", "type": "string", - "required": false + "required": false, + "literalValue": "BR" }, { "method": "maybeAttrString", @@ -74785,7 +90592,21 @@ "name": "flow", "wireName": "flow", "type": "enum", - "required": false + "required": false, + "enumRef": { + "name": "ENUM_P2M_P2P", + "module": "WASmaxInBrPaymentEnums", + "variants": [ + { + "name": "p2m", + "value": "p2m" + }, + { + "name": "p2p", + "value": "p2p" + } + ] + } }, { "method": "attrString", @@ -74855,7 +90676,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ], "variants": [ @@ -74868,6 +90690,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -74887,14 +90723,29 @@ "name": "type", "wireName": "type", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_PAYONDELIVERY_PIXKEY", + "module": "WASmaxInBrPaymentEnums", + "variants": [ + { + "name": "pay_on_delivery", + "value": "pay_on_delivery" + }, + { + "name": "pix_key", + "value": "pix_key" + } + ] + } }, { "method": "maybeAttrString", "name": "country", "wireName": "country", "type": "string", - "required": false + "required": false, + "literalValue": "BR" }, { "method": "maybeAttrString", @@ -74908,7 +90759,21 @@ "name": "flow", "wireName": "flow", "type": "enum", - "required": false + "required": false, + "enumRef": { + "name": "ENUM_P2M_P2P", + "module": "WASmaxInBrPaymentEnums", + "variants": [ + { + "name": "p2m", + "value": "p2m" + }, + { + "name": "p2p", + "value": "p2p" + } + ] + } }, { "method": "attrString", @@ -74978,7 +90843,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ] }, @@ -74986,15 +90852,32 @@ "tag": "CreateCustomPaymentMethodResponseIQErrorWithCodeAndReason", "moduleName": "WASmaxInBrPaymentCreateCustomPaymentMethodResponseIQErrorWithCodeAndReason", "kind": "error", + "errorArms": [ + {} + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", "value": "error" + }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] } ], "fields": [ @@ -75003,7 +90886,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "attrString", @@ -75145,7 +91029,37 @@ "name": "state", "wireName": "state", "type": "enum", - "required": false + "required": false, + "enumRef": { + "name": "ENUM_ACTIVE_DELETED_INACTIVE_NEEDSRETOKENIZATION_NEEDSRETOKENIZATIONDELETED_SUSPENDED", + "module": "WASmaxInBrPaymentEnums", + "variants": [ + { + "name": "ACTIVE", + "value": "ACTIVE" + }, + { + "name": "DELETED", + "value": "DELETED" + }, + { + "name": "INACTIVE", + "value": "INACTIVE" + }, + { + "name": "NEEDS_RETOKENIZATION", + "value": "NEEDS_RETOKENIZATION" + }, + { + "name": "NEEDS_RETOKENIZATION_DELETED", + "value": "NEEDS_RETOKENIZATION_DELETED" + }, + { + "name": "SUSPENDED", + "value": "SUSPENDED" + } + ] + } }, { "method": "maybeAttrString", @@ -75208,7 +91122,29 @@ "name": "displayState", "wireName": "display-state", "type": "enum", - "required": false + "required": false, + "enumRef": { + "name": "ENUM_ACTIVE_EXPIRED_SUSPENDED_VOIDED", + "module": "WASmaxInBrPaymentEnums", + "variants": [ + { + "name": "ACTIVE", + "value": "ACTIVE" + }, + { + "name": "EXPIRED", + "value": "EXPIRED" + }, + { + "name": "SUSPENDED", + "value": "SUSPENDED" + }, + { + "name": "VOIDED", + "value": "VOIDED" + } + ] + } }, { "method": "attrEnum", @@ -75343,6 +91279,24 @@ "wireName": "p2p-send", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_DISABLED_ENABLED_REQUIRESVERIFICATION", + "module": "WASmaxInBrPaymentEnums", + "variants": [ + { + "name": "DISABLED", + "value": "DISABLED" + }, + { + "name": "ENABLED", + "value": "ENABLED" + }, + { + "name": "REQUIRES_VERIFICATION", + "value": "REQUIRES_VERIFICATION" + } + ] + }, "sourcePath": [ "capabilities" ] @@ -75353,6 +91307,24 @@ "wireName": "p2p-receive", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_DISABLED_ENABLED_REQUIRESVERIFICATION", + "module": "WASmaxInBrPaymentEnums", + "variants": [ + { + "name": "DISABLED", + "value": "DISABLED" + }, + { + "name": "ENABLED", + "value": "ENABLED" + }, + { + "name": "REQUIRES_VERIFICATION", + "value": "REQUIRES_VERIFICATION" + } + ] + }, "sourcePath": [ "capabilities" ] @@ -75363,6 +91335,24 @@ "wireName": "p2m-send", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_DISABLED_ENABLED_REQUIRESVERIFICATION", + "module": "WASmaxInBrPaymentEnums", + "variants": [ + { + "name": "DISABLED", + "value": "DISABLED" + }, + { + "name": "ENABLED", + "value": "ENABLED" + }, + { + "name": "REQUIRES_VERIFICATION", + "value": "REQUIRES_VERIFICATION" + } + ] + }, "sourcePath": [ "capabilities" ] @@ -75373,6 +91363,24 @@ "wireName": "p2m-receive", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_DISABLED_ENABLED_REQUIRESVERIFICATION", + "module": "WASmaxInBrPaymentEnums", + "variants": [ + { + "name": "DISABLED", + "value": "DISABLED" + }, + { + "name": "ENABLED", + "value": "ENABLED" + }, + { + "name": "REQUIRES_VERIFICATION", + "value": "REQUIRES_VERIFICATION" + } + ] + }, "sourcePath": [ "capabilities" ] @@ -75464,7 +91472,29 @@ "name": "displayState", "wireName": "display-state", "type": "enum", - "required": false + "required": false, + "enumRef": { + "name": "ENUM_ACTIVE_EXPIRED_SUSPENDED_VOIDED", + "module": "WASmaxInBrPaymentEnums", + "variants": [ + { + "name": "ACTIVE", + "value": "ACTIVE" + }, + { + "name": "EXPIRED", + "value": "EXPIRED" + }, + { + "name": "SUSPENDED", + "value": "SUSPENDED" + }, + { + "name": "VOIDED", + "value": "VOIDED" + } + ] + } }, { "method": "attrEnum", @@ -75599,6 +91629,24 @@ "wireName": "p2p-send", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_DISABLED_ENABLED_REQUIRESVERIFICATION", + "module": "WASmaxInBrPaymentEnums", + "variants": [ + { + "name": "DISABLED", + "value": "DISABLED" + }, + { + "name": "ENABLED", + "value": "ENABLED" + }, + { + "name": "REQUIRES_VERIFICATION", + "value": "REQUIRES_VERIFICATION" + } + ] + }, "sourcePath": [ "capabilities" ] @@ -75609,6 +91657,24 @@ "wireName": "p2p-receive", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_DISABLED_ENABLED_REQUIRESVERIFICATION", + "module": "WASmaxInBrPaymentEnums", + "variants": [ + { + "name": "DISABLED", + "value": "DISABLED" + }, + { + "name": "ENABLED", + "value": "ENABLED" + }, + { + "name": "REQUIRES_VERIFICATION", + "value": "REQUIRES_VERIFICATION" + } + ] + }, "sourcePath": [ "capabilities" ] @@ -75619,6 +91685,24 @@ "wireName": "p2m-send", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_DISABLED_ENABLED_REQUIRESVERIFICATION", + "module": "WASmaxInBrPaymentEnums", + "variants": [ + { + "name": "DISABLED", + "value": "DISABLED" + }, + { + "name": "ENABLED", + "value": "ENABLED" + }, + { + "name": "REQUIRES_VERIFICATION", + "value": "REQUIRES_VERIFICATION" + } + ] + }, "sourcePath": [ "capabilities" ] @@ -75629,6 +91713,24 @@ "wireName": "p2m-receive", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_DISABLED_ENABLED_REQUIRESVERIFICATION", + "module": "WASmaxInBrPaymentEnums", + "variants": [ + { + "name": "DISABLED", + "value": "DISABLED" + }, + { + "name": "ENABLED", + "value": "ENABLED" + }, + { + "name": "REQUIRES_VERIFICATION", + "value": "REQUIRES_VERIFICATION" + } + ] + }, "sourcePath": [ "capabilities" ] @@ -75684,7 +91786,29 @@ "name": "displayState", "wireName": "display-state", "type": "enum", - "required": false + "required": false, + "enumRef": { + "name": "ENUM_ACTIVE_EXPIRED_SUSPENDED_VOIDED", + "module": "WASmaxInBrPaymentEnums", + "variants": [ + { + "name": "ACTIVE", + "value": "ACTIVE" + }, + { + "name": "EXPIRED", + "value": "EXPIRED" + }, + { + "name": "SUSPENDED", + "value": "SUSPENDED" + }, + { + "name": "VOIDED", + "value": "VOIDED" + } + ] + } }, { "method": "attrEnum", @@ -75819,6 +91943,24 @@ "wireName": "p2p-send", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_DISABLED_ENABLED_REQUIRESVERIFICATION", + "module": "WASmaxInBrPaymentEnums", + "variants": [ + { + "name": "DISABLED", + "value": "DISABLED" + }, + { + "name": "ENABLED", + "value": "ENABLED" + }, + { + "name": "REQUIRES_VERIFICATION", + "value": "REQUIRES_VERIFICATION" + } + ] + }, "sourcePath": [ "capabilities" ] @@ -75829,6 +91971,24 @@ "wireName": "p2p-receive", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_DISABLED_ENABLED_REQUIRESVERIFICATION", + "module": "WASmaxInBrPaymentEnums", + "variants": [ + { + "name": "DISABLED", + "value": "DISABLED" + }, + { + "name": "ENABLED", + "value": "ENABLED" + }, + { + "name": "REQUIRES_VERIFICATION", + "value": "REQUIRES_VERIFICATION" + } + ] + }, "sourcePath": [ "capabilities" ] @@ -75839,6 +91999,24 @@ "wireName": "p2m-send", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_DISABLED_ENABLED_REQUIRESVERIFICATION", + "module": "WASmaxInBrPaymentEnums", + "variants": [ + { + "name": "DISABLED", + "value": "DISABLED" + }, + { + "name": "ENABLED", + "value": "ENABLED" + }, + { + "name": "REQUIRES_VERIFICATION", + "value": "REQUIRES_VERIFICATION" + } + ] + }, "sourcePath": [ "capabilities" ] @@ -75849,6 +92027,24 @@ "wireName": "p2m-receive", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_DISABLED_ENABLED_REQUIRESVERIFICATION", + "module": "WASmaxInBrPaymentEnums", + "variants": [ + { + "name": "DISABLED", + "value": "DISABLED" + }, + { + "name": "ENABLED", + "value": "ENABLED" + }, + { + "name": "REQUIRES_VERIFICATION", + "value": "REQUIRES_VERIFICATION" + } + ] + }, "sourcePath": [ "capabilities" ] @@ -75878,7 +92074,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "upi" }, { "method": "maybeAttrString", @@ -76146,7 +92343,49 @@ "name": "displayState", "wireName": "display-state", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_ACCOUNTPENDINGLINKING_ACTIVE_EXTERNALLYDISABLED_HARDBLOCKED_INACTIVE_INITED_INTEGRITYBLOCKED_PENDING_SOFTBLOCKED", + "module": "WASmaxInBrPaymentEnums", + "variants": [ + { + "name": "ACCOUNT_PENDING_LINKING", + "value": "ACCOUNT_PENDING_LINKING" + }, + { + "name": "ACTIVE", + "value": "ACTIVE" + }, + { + "name": "EXTERNALLY_DISABLED", + "value": "EXTERNALLY_DISABLED" + }, + { + "name": "HARD_BLOCKED", + "value": "HARD_BLOCKED" + }, + { + "name": "INACTIVE", + "value": "INACTIVE" + }, + { + "name": "INITED", + "value": "INITED" + }, + { + "name": "INTEGRITY_BLOCKED", + "value": "INTEGRITY_BLOCKED" + }, + { + "name": "PENDING", + "value": "PENDING" + }, + { + "name": "SOFT_BLOCKED", + "value": "SOFT_BLOCKED" + } + ] + } }, { "method": "maybeAttrString", @@ -76283,7 +92522,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "bank" }, { "method": "maybeAttrString", @@ -76311,7 +92551,25 @@ "name": "verificationStatus", "wireName": "verification-status", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_FAILED_PENDING_VERIFIED", + "module": "WASmaxInBrPaymentEnums", + "variants": [ + { + "name": "FAILED", + "value": "FAILED" + }, + { + "name": "PENDING", + "value": "PENDING" + }, + { + "name": "VERIFIED", + "value": "VERIFIED" + } + ] + } }, { "method": "attrString", @@ -76369,7 +92627,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "prepaid-card" }, { "method": "attrString", @@ -76467,14 +92726,86 @@ "name": "aliasType", "wireName": "alias_type", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_MOBILENUMBER_NUMERICID", + "module": "WASmaxInBrPaymentEnums", + "variants": [ + { + "name": "mobile_number", + "value": "mobile_number" + }, + { + "name": "numeric_id", + "value": "numeric_id" + } + ] + } }, { "method": "maybeAttrEnum", "name": "aliasStatus", "wireName": "alias_status", "type": "enum", - "required": false + "required": false, + "enumRef": { + "name": "ENUM_ACTIVE_ACTIVEPENDING_ACTIVESTATUSPENDING_AVAILABLE_AVAILABLEPENDING_AVAILABLESTATUSPENDING_BLOCKED_DEREGISTERED_DEREGISTEREDPENDING_INACTIVE_INACTIVEPENDING_INACTIVESTATUSPENDING_UNKNOWN", + "module": "WASmaxInBrPaymentEnums", + "variants": [ + { + "name": "active", + "value": "active" + }, + { + "name": "active_pending", + "value": "active_pending" + }, + { + "name": "active_status_pending", + "value": "active_status_pending" + }, + { + "name": "available", + "value": "available" + }, + { + "name": "available_pending", + "value": "available_pending" + }, + { + "name": "available_status_pending", + "value": "available_status_pending" + }, + { + "name": "blocked", + "value": "blocked" + }, + { + "name": "deregistered", + "value": "deregistered" + }, + { + "name": "deregistered_pending", + "value": "deregistered_pending" + }, + { + "name": "inactive", + "value": "inactive" + }, + { + "name": "inactive_pending", + "value": "inactive_pending" + }, + { + "name": "inactive_status_pending", + "value": "inactive_status_pending" + }, + { + "name": "unknown", + "value": "unknown" + } + ] + } } ], "repeats": true @@ -76491,14 +92822,29 @@ "name": "type", "wireName": "type", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_PAYONDELIVERY_PIXKEY", + "module": "WASmaxInBrPaymentEnums", + "variants": [ + { + "name": "pay_on_delivery", + "value": "pay_on_delivery" + }, + { + "name": "pix_key", + "value": "pix_key" + } + ] + } }, { "method": "maybeAttrString", "name": "country", "wireName": "country", "type": "string", - "required": false + "required": false, + "literalValue": "BR" }, { "method": "maybeAttrString", @@ -76512,7 +92858,21 @@ "name": "flow", "wireName": "flow", "type": "enum", - "required": false + "required": false, + "enumRef": { + "name": "ENUM_P2M_P2P", + "module": "WASmaxInBrPaymentEnums", + "variants": [ + { + "name": "p2m", + "value": "p2m" + }, + { + "name": "p2p", + "value": "p2p" + } + ] + } }, { "method": "attrString", @@ -76582,7 +92942,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ], "variants": [ @@ -76595,6 +92956,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -76672,7 +93047,37 @@ "name": "state", "wireName": "state", "type": "enum", - "required": false + "required": false, + "enumRef": { + "name": "ENUM_ACTIVE_DELETED_INACTIVE_NEEDSRETOKENIZATION_NEEDSRETOKENIZATIONDELETED_SUSPENDED", + "module": "WASmaxInBrPaymentEnums", + "variants": [ + { + "name": "ACTIVE", + "value": "ACTIVE" + }, + { + "name": "DELETED", + "value": "DELETED" + }, + { + "name": "INACTIVE", + "value": "INACTIVE" + }, + { + "name": "NEEDS_RETOKENIZATION", + "value": "NEEDS_RETOKENIZATION" + }, + { + "name": "NEEDS_RETOKENIZATION_DELETED", + "value": "NEEDS_RETOKENIZATION_DELETED" + }, + { + "name": "SUSPENDED", + "value": "SUSPENDED" + } + ] + } }, { "method": "maybeAttrString", @@ -76735,7 +93140,29 @@ "name": "displayState", "wireName": "display-state", "type": "enum", - "required": false + "required": false, + "enumRef": { + "name": "ENUM_ACTIVE_EXPIRED_SUSPENDED_VOIDED", + "module": "WASmaxInBrPaymentEnums", + "variants": [ + { + "name": "ACTIVE", + "value": "ACTIVE" + }, + { + "name": "EXPIRED", + "value": "EXPIRED" + }, + { + "name": "SUSPENDED", + "value": "SUSPENDED" + }, + { + "name": "VOIDED", + "value": "VOIDED" + } + ] + } }, { "method": "attrEnum", @@ -76870,6 +93297,24 @@ "wireName": "p2p-send", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_DISABLED_ENABLED_REQUIRESVERIFICATION", + "module": "WASmaxInBrPaymentEnums", + "variants": [ + { + "name": "DISABLED", + "value": "DISABLED" + }, + { + "name": "ENABLED", + "value": "ENABLED" + }, + { + "name": "REQUIRES_VERIFICATION", + "value": "REQUIRES_VERIFICATION" + } + ] + }, "sourcePath": [ "capabilities" ] @@ -76880,6 +93325,24 @@ "wireName": "p2p-receive", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_DISABLED_ENABLED_REQUIRESVERIFICATION", + "module": "WASmaxInBrPaymentEnums", + "variants": [ + { + "name": "DISABLED", + "value": "DISABLED" + }, + { + "name": "ENABLED", + "value": "ENABLED" + }, + { + "name": "REQUIRES_VERIFICATION", + "value": "REQUIRES_VERIFICATION" + } + ] + }, "sourcePath": [ "capabilities" ] @@ -76890,6 +93353,24 @@ "wireName": "p2m-send", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_DISABLED_ENABLED_REQUIRESVERIFICATION", + "module": "WASmaxInBrPaymentEnums", + "variants": [ + { + "name": "DISABLED", + "value": "DISABLED" + }, + { + "name": "ENABLED", + "value": "ENABLED" + }, + { + "name": "REQUIRES_VERIFICATION", + "value": "REQUIRES_VERIFICATION" + } + ] + }, "sourcePath": [ "capabilities" ] @@ -76900,6 +93381,24 @@ "wireName": "p2m-receive", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_DISABLED_ENABLED_REQUIRESVERIFICATION", + "module": "WASmaxInBrPaymentEnums", + "variants": [ + { + "name": "DISABLED", + "value": "DISABLED" + }, + { + "name": "ENABLED", + "value": "ENABLED" + }, + { + "name": "REQUIRES_VERIFICATION", + "value": "REQUIRES_VERIFICATION" + } + ] + }, "sourcePath": [ "capabilities" ] @@ -76991,7 +93490,29 @@ "name": "displayState", "wireName": "display-state", "type": "enum", - "required": false + "required": false, + "enumRef": { + "name": "ENUM_ACTIVE_EXPIRED_SUSPENDED_VOIDED", + "module": "WASmaxInBrPaymentEnums", + "variants": [ + { + "name": "ACTIVE", + "value": "ACTIVE" + }, + { + "name": "EXPIRED", + "value": "EXPIRED" + }, + { + "name": "SUSPENDED", + "value": "SUSPENDED" + }, + { + "name": "VOIDED", + "value": "VOIDED" + } + ] + } }, { "method": "attrEnum", @@ -77126,6 +93647,24 @@ "wireName": "p2p-send", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_DISABLED_ENABLED_REQUIRESVERIFICATION", + "module": "WASmaxInBrPaymentEnums", + "variants": [ + { + "name": "DISABLED", + "value": "DISABLED" + }, + { + "name": "ENABLED", + "value": "ENABLED" + }, + { + "name": "REQUIRES_VERIFICATION", + "value": "REQUIRES_VERIFICATION" + } + ] + }, "sourcePath": [ "capabilities" ] @@ -77136,6 +93675,24 @@ "wireName": "p2p-receive", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_DISABLED_ENABLED_REQUIRESVERIFICATION", + "module": "WASmaxInBrPaymentEnums", + "variants": [ + { + "name": "DISABLED", + "value": "DISABLED" + }, + { + "name": "ENABLED", + "value": "ENABLED" + }, + { + "name": "REQUIRES_VERIFICATION", + "value": "REQUIRES_VERIFICATION" + } + ] + }, "sourcePath": [ "capabilities" ] @@ -77146,6 +93703,24 @@ "wireName": "p2m-send", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_DISABLED_ENABLED_REQUIRESVERIFICATION", + "module": "WASmaxInBrPaymentEnums", + "variants": [ + { + "name": "DISABLED", + "value": "DISABLED" + }, + { + "name": "ENABLED", + "value": "ENABLED" + }, + { + "name": "REQUIRES_VERIFICATION", + "value": "REQUIRES_VERIFICATION" + } + ] + }, "sourcePath": [ "capabilities" ] @@ -77156,6 +93731,24 @@ "wireName": "p2m-receive", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_DISABLED_ENABLED_REQUIRESVERIFICATION", + "module": "WASmaxInBrPaymentEnums", + "variants": [ + { + "name": "DISABLED", + "value": "DISABLED" + }, + { + "name": "ENABLED", + "value": "ENABLED" + }, + { + "name": "REQUIRES_VERIFICATION", + "value": "REQUIRES_VERIFICATION" + } + ] + }, "sourcePath": [ "capabilities" ] @@ -77211,7 +93804,29 @@ "name": "displayState", "wireName": "display-state", "type": "enum", - "required": false + "required": false, + "enumRef": { + "name": "ENUM_ACTIVE_EXPIRED_SUSPENDED_VOIDED", + "module": "WASmaxInBrPaymentEnums", + "variants": [ + { + "name": "ACTIVE", + "value": "ACTIVE" + }, + { + "name": "EXPIRED", + "value": "EXPIRED" + }, + { + "name": "SUSPENDED", + "value": "SUSPENDED" + }, + { + "name": "VOIDED", + "value": "VOIDED" + } + ] + } }, { "method": "attrEnum", @@ -77346,6 +93961,24 @@ "wireName": "p2p-send", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_DISABLED_ENABLED_REQUIRESVERIFICATION", + "module": "WASmaxInBrPaymentEnums", + "variants": [ + { + "name": "DISABLED", + "value": "DISABLED" + }, + { + "name": "ENABLED", + "value": "ENABLED" + }, + { + "name": "REQUIRES_VERIFICATION", + "value": "REQUIRES_VERIFICATION" + } + ] + }, "sourcePath": [ "capabilities" ] @@ -77356,6 +93989,24 @@ "wireName": "p2p-receive", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_DISABLED_ENABLED_REQUIRESVERIFICATION", + "module": "WASmaxInBrPaymentEnums", + "variants": [ + { + "name": "DISABLED", + "value": "DISABLED" + }, + { + "name": "ENABLED", + "value": "ENABLED" + }, + { + "name": "REQUIRES_VERIFICATION", + "value": "REQUIRES_VERIFICATION" + } + ] + }, "sourcePath": [ "capabilities" ] @@ -77366,6 +94017,24 @@ "wireName": "p2m-send", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_DISABLED_ENABLED_REQUIRESVERIFICATION", + "module": "WASmaxInBrPaymentEnums", + "variants": [ + { + "name": "DISABLED", + "value": "DISABLED" + }, + { + "name": "ENABLED", + "value": "ENABLED" + }, + { + "name": "REQUIRES_VERIFICATION", + "value": "REQUIRES_VERIFICATION" + } + ] + }, "sourcePath": [ "capabilities" ] @@ -77376,6 +94045,24 @@ "wireName": "p2m-receive", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_DISABLED_ENABLED_REQUIRESVERIFICATION", + "module": "WASmaxInBrPaymentEnums", + "variants": [ + { + "name": "DISABLED", + "value": "DISABLED" + }, + { + "name": "ENABLED", + "value": "ENABLED" + }, + { + "name": "REQUIRES_VERIFICATION", + "value": "REQUIRES_VERIFICATION" + } + ] + }, "sourcePath": [ "capabilities" ] @@ -77405,7 +94092,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "upi" }, { "method": "maybeAttrString", @@ -77673,7 +94361,49 @@ "name": "displayState", "wireName": "display-state", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_ACCOUNTPENDINGLINKING_ACTIVE_EXTERNALLYDISABLED_HARDBLOCKED_INACTIVE_INITED_INTEGRITYBLOCKED_PENDING_SOFTBLOCKED", + "module": "WASmaxInBrPaymentEnums", + "variants": [ + { + "name": "ACCOUNT_PENDING_LINKING", + "value": "ACCOUNT_PENDING_LINKING" + }, + { + "name": "ACTIVE", + "value": "ACTIVE" + }, + { + "name": "EXTERNALLY_DISABLED", + "value": "EXTERNALLY_DISABLED" + }, + { + "name": "HARD_BLOCKED", + "value": "HARD_BLOCKED" + }, + { + "name": "INACTIVE", + "value": "INACTIVE" + }, + { + "name": "INITED", + "value": "INITED" + }, + { + "name": "INTEGRITY_BLOCKED", + "value": "INTEGRITY_BLOCKED" + }, + { + "name": "PENDING", + "value": "PENDING" + }, + { + "name": "SOFT_BLOCKED", + "value": "SOFT_BLOCKED" + } + ] + } }, { "method": "maybeAttrString", @@ -77810,7 +94540,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "bank" }, { "method": "maybeAttrString", @@ -77838,7 +94569,25 @@ "name": "verificationStatus", "wireName": "verification-status", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_FAILED_PENDING_VERIFIED", + "module": "WASmaxInBrPaymentEnums", + "variants": [ + { + "name": "FAILED", + "value": "FAILED" + }, + { + "name": "PENDING", + "value": "PENDING" + }, + { + "name": "VERIFIED", + "value": "VERIFIED" + } + ] + } }, { "method": "attrString", @@ -77896,7 +94645,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "prepaid-card" }, { "method": "attrString", @@ -77994,14 +94744,86 @@ "name": "aliasType", "wireName": "alias_type", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_MOBILENUMBER_NUMERICID", + "module": "WASmaxInBrPaymentEnums", + "variants": [ + { + "name": "mobile_number", + "value": "mobile_number" + }, + { + "name": "numeric_id", + "value": "numeric_id" + } + ] + } }, { "method": "maybeAttrEnum", "name": "aliasStatus", "wireName": "alias_status", "type": "enum", - "required": false + "required": false, + "enumRef": { + "name": "ENUM_ACTIVE_ACTIVEPENDING_ACTIVESTATUSPENDING_AVAILABLE_AVAILABLEPENDING_AVAILABLESTATUSPENDING_BLOCKED_DEREGISTERED_DEREGISTEREDPENDING_INACTIVE_INACTIVEPENDING_INACTIVESTATUSPENDING_UNKNOWN", + "module": "WASmaxInBrPaymentEnums", + "variants": [ + { + "name": "active", + "value": "active" + }, + { + "name": "active_pending", + "value": "active_pending" + }, + { + "name": "active_status_pending", + "value": "active_status_pending" + }, + { + "name": "available", + "value": "available" + }, + { + "name": "available_pending", + "value": "available_pending" + }, + { + "name": "available_status_pending", + "value": "available_status_pending" + }, + { + "name": "blocked", + "value": "blocked" + }, + { + "name": "deregistered", + "value": "deregistered" + }, + { + "name": "deregistered_pending", + "value": "deregistered_pending" + }, + { + "name": "inactive", + "value": "inactive" + }, + { + "name": "inactive_pending", + "value": "inactive_pending" + }, + { + "name": "inactive_status_pending", + "value": "inactive_status_pending" + }, + { + "name": "unknown", + "value": "unknown" + } + ] + } } ], "repeats": true @@ -78018,14 +94840,29 @@ "name": "type", "wireName": "type", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_PAYONDELIVERY_PIXKEY", + "module": "WASmaxInBrPaymentEnums", + "variants": [ + { + "name": "pay_on_delivery", + "value": "pay_on_delivery" + }, + { + "name": "pix_key", + "value": "pix_key" + } + ] + } }, { "method": "maybeAttrString", "name": "country", "wireName": "country", "type": "string", - "required": false + "required": false, + "literalValue": "BR" }, { "method": "maybeAttrString", @@ -78039,7 +94876,21 @@ "name": "flow", "wireName": "flow", "type": "enum", - "required": false + "required": false, + "enumRef": { + "name": "ENUM_P2M_P2P", + "module": "WASmaxInBrPaymentEnums", + "variants": [ + { + "name": "p2m", + "value": "p2m" + }, + { + "name": "p2p", + "value": "p2p" + } + ] + } }, { "method": "attrString", @@ -78109,7 +94960,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ] }, @@ -78117,15 +94969,32 @@ "tag": "RemoveCustomPaymentMethodResponseError", "moduleName": "WASmaxInBrPaymentRemoveCustomPaymentMethodResponseError", "kind": "error", + "errorArms": [ + {} + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", "value": "error" + }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] } ], "fields": [ @@ -78134,7 +95003,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "attrString", @@ -78235,6 +95105,20 @@ "wireName": "type", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_IMAGE_PREVIEW", + "module": "WASmaxInProfilePictureEnums", + "variants": [ + { + "name": "image", + "value": "image" + }, + { + "name": "preview", + "value": "preview" + } + ] + }, "sourcePath": [ "picture" ] @@ -78275,6 +95159,20 @@ "wireName": "has_staging", "type": "enum", "required": false, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInProfilePictureEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + }, "sourcePath": [ "picture" ] @@ -78284,7 +95182,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ], "variants": [ @@ -78297,6 +95196,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -78320,6 +95233,20 @@ "wireName": "type", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_IMAGE_PREVIEW", + "module": "WASmaxInProfilePictureEnums", + "variants": [ + { + "name": "image", + "value": "image" + }, + { + "name": "preview", + "value": "preview" + } + ] + }, "sourcePath": [ "picture" ] @@ -78360,6 +95287,20 @@ "wireName": "has_staging", "type": "enum", "required": false, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInProfilePictureEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + }, "sourcePath": [ "picture" ] @@ -78369,7 +95310,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ] }, @@ -78382,6 +95324,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -78394,7 +95350,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "child", @@ -78438,6 +95395,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -78461,6 +95432,20 @@ "wireName": "type", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_IMAGE_PREVIEW", + "module": "WASmaxInProfilePictureEnums", + "variants": [ + { + "name": "image", + "value": "image" + }, + { + "name": "preview", + "value": "preview" + } + ] + }, "sourcePath": [ "picture" ] @@ -78471,6 +95456,20 @@ "wireName": "has_staging", "type": "enum", "required": false, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInProfilePictureEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + }, "sourcePath": [ "picture" ] @@ -78489,7 +95488,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ] }, @@ -78502,6 +95502,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -78514,7 +95528,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ] }, @@ -78522,11 +95537,62 @@ "tag": "GetResponseError", "moduleName": "WASmaxInProfilePictureGetResponseError", "kind": "error", + "errorArms": [ + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorNotAuthorized", + "code": 401, + "text": "not-authorized" + }, + { + "name": "IQErrorItemNotFound", + "code": 404, + "text": "item-not-found" + }, + { + "name": "IQErrorRateOverlimit", + "code": 429, + "text": "rate-overlimit" + }, + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorFeatureNotImplemented", + "code": 501, + "text": "feature-not-implemented" + }, + { + "name": "IQErrorServiceUnavailable", + "code": 503, + "text": "service-unavailable" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -78539,7 +95605,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -78555,14 +95622,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -78574,6 +95643,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -78585,14 +95659,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-authorized" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "401" } ], "assertions": [ @@ -78604,6 +95680,11 @@ "kind": "attr", "name": "text", "value": "not-authorized" + }, + { + "kind": "attr", + "name": "code", + "value": "401" } ] }, @@ -78615,14 +95696,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "item-not-found" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "404" } ], "assertions": [ @@ -78634,6 +95717,11 @@ "kind": "attr", "name": "text", "value": "item-not-found" + }, + { + "kind": "attr", + "name": "code", + "value": "404" } ] }, @@ -78645,14 +95733,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "rate-overlimit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "429" } ], "assertions": [ @@ -78664,6 +95754,11 @@ "kind": "attr", "name": "text", "value": "rate-overlimit" + }, + { + "kind": "attr", + "name": "code", + "value": "429" } ] }, @@ -78675,14 +95770,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -78694,6 +95791,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -78705,14 +95807,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "feature-not-implemented" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "501" } ], "assertions": [ @@ -78724,6 +95828,11 @@ "kind": "attr", "name": "text", "value": "feature-not-implemented" + }, + { + "kind": "attr", + "name": "code", + "value": "501" } ] }, @@ -78735,14 +95844,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "assertions": [ @@ -78754,6 +95865,11 @@ "kind": "attr", "name": "text", "value": "service-unavailable" + }, + { + "kind": "attr", + "name": "code", + "value": "503" } ] } @@ -78966,7 +96082,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ], "variants": [ @@ -78979,6 +96096,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -78991,7 +96122,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ] }, @@ -78999,11 +96131,42 @@ "tag": "SendBufferResponseErrorNoRetry", "moduleName": "WASmaxInStatsSendBufferResponseErrorNoRetry", "kind": "error", + "errorArms": [ + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorNotAcceptable", + "code": 406, + "text": "not-acceptable" + }, + { + "name": "IQErrorFeatureNotImplemented", + "code": 501, + "text": "feature-not-implemented" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -79016,7 +96179,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -79032,14 +96196,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -79051,6 +96217,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -79062,14 +96233,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-acceptable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "406" }, { "method": "child", @@ -79105,6 +96278,11 @@ "kind": "attr", "name": "text", "value": "not-acceptable" + }, + { + "kind": "attr", + "name": "code", + "value": "406" } ] }, @@ -79116,14 +96294,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "feature-not-implemented" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "501" } ], "assertions": [ @@ -79135,6 +96315,11 @@ "kind": "attr", "name": "text", "value": "feature-not-implemented" + }, + { + "kind": "attr", + "name": "code", + "value": "501" } ] } @@ -79148,12 +96333,32 @@ { "tag": "SendBufferResponseErrorRetry", "moduleName": "WASmaxInStatsSendBufferResponseErrorRetry", - "kind": "error", + "kind": "server_error", + "errorArms": [ + { + "code": 503, + "text": "service-unavailable" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -79173,14 +96378,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "repeats": false @@ -79190,7 +96397,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" } ] } @@ -79337,14 +96545,16 @@ "name": "version", "wireName": "version", "type": "string", - "required": true + "required": true, + "literalValue": "1" }, { "method": "attrString", "name": "algorithm", "wireName": "algorithm", "type": "string", - "required": true + "required": true, + "literalValue": "rsa2048" }, { "method": "contentBytes", @@ -79398,7 +96608,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "child", @@ -79408,10 +96619,24 @@ "tag": "wf_deleted", "children": [ { - "method": "attrEnum", + "method": "contentEnum", "name": "elementValue", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInWaffleEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + } } ], "repeats": false @@ -79427,6 +96652,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -79446,14 +96685,16 @@ "name": "version", "wireName": "version", "type": "string", - "required": true + "required": true, + "literalValue": "1" }, { "method": "attrString", "name": "algorithm", "wireName": "algorithm", "type": "string", - "required": true + "required": true, + "literalValue": "rsa2048" }, { "method": "contentBytes", @@ -79507,7 +96748,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "child", @@ -79517,10 +96759,24 @@ "tag": "wf_deleted", "children": [ { - "method": "attrEnum", + "method": "contentEnum", "name": "elementValue", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInWaffleEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + } } ], "repeats": false @@ -79531,11 +96787,87 @@ "tag": "EncryptedPayloadRequestResponseError", "moduleName": "WASmaxInWaffleEncryptedPayloadRequestResponseError", "kind": "error", + "errorArms": [ + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorRequestTimeout", + "code": 408, + "text": "request-timeout" + }, + { + "name": "IQErrorPayloadEncDec", + "code": 480, + "text": "payload-enc-dec-failed" + }, + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorServiceUnavailable", + "code": 503, + "text": "service-unavailable" + }, + { + "name": "IQErrorNotAuthorized", + "code": 401, + "text": "not-authorized" + }, + { + "name": "IQErrorRateOverlimit", + "code": 429, + "text": "rate-overlimit" + }, + { + "name": "IQErrorNotAllowed", + "code": 405, + "text": "not-allowed" + }, + { + "name": "IQErrorConflict", + "code": 409, + "text": "conflict" + }, + { + "name": "IQErrorWFNotFound", + "code": 483, + "text": "wf-not-found" + }, + { + "name": "IQErrorWFSuspended", + "code": 484, + "text": "wf-suspended" + }, + { + "name": "IQErrorWFStateMismatch", + "code": 485, + "text": "wf-state-mismatch" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -79548,7 +96880,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -79564,14 +96897,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -79583,6 +96918,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -79594,14 +96934,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "request-timeout" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "408" } ], "assertions": [ @@ -79613,6 +96955,11 @@ "kind": "attr", "name": "text", "value": "request-timeout" + }, + { + "kind": "attr", + "name": "code", + "value": "408" } ] }, @@ -79624,14 +96971,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "payload-enc-dec-failed" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "480" } ], "assertions": [ @@ -79643,6 +96992,11 @@ "kind": "attr", "name": "text", "value": "payload-enc-dec-failed" + }, + { + "kind": "attr", + "name": "code", + "value": "480" } ] }, @@ -79654,14 +97008,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -79673,6 +97029,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -79684,14 +97045,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "assertions": [ @@ -79703,6 +97066,11 @@ "kind": "attr", "name": "text", "value": "service-unavailable" + }, + { + "kind": "attr", + "name": "code", + "value": "503" } ] }, @@ -79714,14 +97082,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-authorized" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "401" } ], "assertions": [ @@ -79733,6 +97103,11 @@ "kind": "attr", "name": "text", "value": "not-authorized" + }, + { + "kind": "attr", + "name": "code", + "value": "401" } ] }, @@ -79744,14 +97119,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "rate-overlimit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "429" } ], "assertions": [ @@ -79763,6 +97140,11 @@ "kind": "attr", "name": "text", "value": "rate-overlimit" + }, + { + "kind": "attr", + "name": "code", + "value": "429" } ] }, @@ -79774,14 +97156,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-allowed" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "405" } ], "assertions": [ @@ -79793,6 +97177,11 @@ "kind": "attr", "name": "text", "value": "not-allowed" + }, + { + "kind": "attr", + "name": "code", + "value": "405" } ] }, @@ -79804,14 +97193,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "conflict" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "409" } ], "assertions": [ @@ -79823,6 +97214,11 @@ "kind": "attr", "name": "text", "value": "conflict" + }, + { + "kind": "attr", + "name": "code", + "value": "409" } ] }, @@ -79834,14 +97230,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "wf-not-found" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "483" } ], "assertions": [ @@ -79853,6 +97251,11 @@ "kind": "attr", "name": "text", "value": "wf-not-found" + }, + { + "kind": "attr", + "name": "code", + "value": "483" } ] }, @@ -79864,28 +97267,58 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "wf-suspended" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "484" }, { "method": "maybeAttrEnum", "name": "ndc", "wireName": "ndc", "type": "enum", - "required": false + "required": false, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInWaffleEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + } }, { "method": "maybeAttrEnum", "name": "npr", "wireName": "npr", "type": "enum", - "required": false + "required": false, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInWaffleEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + } } ], "assertions": [ @@ -79897,6 +97330,11 @@ "kind": "attr", "name": "text", "value": "wf-suspended" + }, + { + "kind": "attr", + "name": "code", + "value": "484" } ] }, @@ -79908,14 +97346,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "wf-state-mismatch" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "485" } ], "assertions": [ @@ -79927,6 +97367,11 @@ "kind": "attr", "name": "text", "value": "wf-state-mismatch" + }, + { + "kind": "attr", + "name": "code", + "value": "485" } ] } @@ -79979,7 +97424,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ], "variants": [ @@ -79992,6 +97438,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -80004,7 +97464,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ] }, @@ -80012,11 +97473,57 @@ "tag": "ForceDeleteStateResponseError", "moduleName": "WASmaxInWaffleForceDeleteStateResponseError", "kind": "error", + "errorArms": [ + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorRequestTimeout", + "code": 408, + "text": "request-timeout" + }, + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorServiceUnavailable", + "code": 503, + "text": "service-unavailable" + }, + { + "name": "IQErrorRateOverlimit", + "code": 429, + "text": "rate-overlimit" + }, + { + "name": "IQErrorNotAllowed", + "code": 405, + "text": "not-allowed" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -80029,7 +97536,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -80045,14 +97553,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -80064,6 +97574,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -80075,14 +97590,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "request-timeout" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "408" } ], "assertions": [ @@ -80094,6 +97611,11 @@ "kind": "attr", "name": "text", "value": "request-timeout" + }, + { + "kind": "attr", + "name": "code", + "value": "408" } ] }, @@ -80105,14 +97627,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -80124,6 +97648,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -80135,14 +97664,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "assertions": [ @@ -80154,6 +97685,11 @@ "kind": "attr", "name": "text", "value": "service-unavailable" + }, + { + "kind": "attr", + "name": "code", + "value": "503" } ] }, @@ -80165,14 +97701,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "rate-overlimit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "429" } ], "assertions": [ @@ -80184,6 +97722,11 @@ "kind": "attr", "name": "text", "value": "rate-overlimit" + }, + { + "kind": "attr", + "name": "code", + "value": "429" } ] }, @@ -80195,14 +97738,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-allowed" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "405" } ], "assertions": [ @@ -80214,6 +97759,11 @@ "kind": "attr", "name": "text", "value": "not-allowed" + }, + { + "kind": "attr", + "name": "code", + "value": "405" } ] } @@ -80255,10 +97805,24 @@ "assertions": [], "fields": [ { - "method": "attrEnum", + "method": "contentEnum", "name": "nprElementValue", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInWaffleEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + }, "sourcePath": [ "npr" ] @@ -80268,7 +97832,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ], "variants": [ @@ -80281,6 +97846,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -80289,10 +97868,24 @@ ], "fields": [ { - "method": "attrEnum", + "method": "contentEnum", "name": "nprElementValue", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInWaffleEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + }, "sourcePath": [ "npr" ] @@ -80302,7 +97895,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ] }, @@ -80310,11 +97904,72 @@ "tag": "ForceSuspendStateResponseError", "moduleName": "WASmaxInWaffleForceSuspendStateResponseError", "kind": "error", + "errorArms": [ + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorRequestTimeout", + "code": 408, + "text": "request-timeout" + }, + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorServiceUnavailable", + "code": 503, + "text": "service-unavailable" + }, + { + "name": "IQErrorRateOverlimit", + "code": 429, + "text": "rate-overlimit" + }, + { + "name": "IQErrorNotAllowed", + "code": 405, + "text": "not-allowed" + }, + { + "name": "IQErrorConflict", + "code": 409, + "text": "conflict" + }, + { + "name": "IQErrorWFNotFound", + "code": 483, + "text": "wf-not-found" + }, + { + "name": "IQErrorWFStateMismatch", + "code": 485, + "text": "wf-state-mismatch" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -80327,7 +97982,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -80343,14 +97999,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -80362,6 +98020,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -80373,14 +98036,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "request-timeout" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "408" } ], "assertions": [ @@ -80392,6 +98057,11 @@ "kind": "attr", "name": "text", "value": "request-timeout" + }, + { + "kind": "attr", + "name": "code", + "value": "408" } ] }, @@ -80403,14 +98073,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -80422,6 +98094,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -80433,14 +98110,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "assertions": [ @@ -80452,6 +98131,11 @@ "kind": "attr", "name": "text", "value": "service-unavailable" + }, + { + "kind": "attr", + "name": "code", + "value": "503" } ] }, @@ -80463,14 +98147,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "rate-overlimit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "429" } ], "assertions": [ @@ -80482,6 +98168,11 @@ "kind": "attr", "name": "text", "value": "rate-overlimit" + }, + { + "kind": "attr", + "name": "code", + "value": "429" } ] }, @@ -80493,14 +98184,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-allowed" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "405" } ], "assertions": [ @@ -80512,6 +98205,11 @@ "kind": "attr", "name": "text", "value": "not-allowed" + }, + { + "kind": "attr", + "name": "code", + "value": "405" } ] }, @@ -80523,14 +98221,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "conflict" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "409" } ], "assertions": [ @@ -80542,6 +98242,11 @@ "kind": "attr", "name": "text", "value": "conflict" + }, + { + "kind": "attr", + "name": "code", + "value": "409" } ] }, @@ -80553,14 +98258,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "wf-not-found" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "483" } ], "assertions": [ @@ -80572,6 +98279,11 @@ "kind": "attr", "name": "text", "value": "wf-not-found" + }, + { + "kind": "attr", + "name": "code", + "value": "483" } ] }, @@ -80583,14 +98295,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "wf-state-mismatch" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "485" } ], "assertions": [ @@ -80602,6 +98316,11 @@ "kind": "attr", "name": "text", "value": "wf-state-mismatch" + }, + { + "kind": "attr", + "name": "code", + "value": "485" } ] } @@ -80681,14 +98400,16 @@ "name": "version", "wireName": "version", "type": "string", - "required": true + "required": true, + "literalValue": "1" }, { "method": "attrString", "name": "algorithm", "wireName": "algorithm", "type": "string", - "required": true + "required": true, + "literalValue": "rsa2048" }, { "method": "contentBytes", @@ -80742,7 +98463,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ], "variants": [ @@ -80755,6 +98477,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -80783,14 +98519,16 @@ "name": "version", "wireName": "version", "type": "string", - "required": true + "required": true, + "literalValue": "1" }, { "method": "attrString", "name": "algorithm", "wireName": "algorithm", "type": "string", - "required": true + "required": true, + "literalValue": "rsa2048" }, { "method": "contentBytes", @@ -80844,7 +98582,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ] }, @@ -80852,11 +98591,92 @@ "tag": "GenerateAccessTokensResponseError", "moduleName": "WASmaxInWaffleGenerateAccessTokensResponseError", "kind": "error", + "errorArms": [ + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorRequestTimeout", + "code": 408, + "text": "request-timeout" + }, + { + "name": "IQErrorPayloadEncDec", + "code": 480, + "text": "payload-enc-dec-failed" + }, + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorServiceUnavailable", + "code": 503, + "text": "service-unavailable" + }, + { + "name": "IQErrorNotAuthorized", + "code": 401, + "text": "not-authorized" + }, + { + "name": "IQErrorRateOverlimit", + "code": 429, + "text": "rate-overlimit" + }, + { + "name": "IQErrorNotAllowed", + "code": 405, + "text": "not-allowed" + }, + { + "name": "IQErrorConflict", + "code": 409, + "text": "conflict" + }, + { + "name": "IQErrorAlreadyExists", + "code": 304, + "text": "already-exists" + }, + { + "name": "IQErrorWFNotFound", + "code": 483, + "text": "wf-not-found" + }, + { + "name": "IQErrorWFStateMismatch", + "code": 485, + "text": "wf-state-mismatch" + }, + { + "name": "IQErrorWFNotAuthorizedInvalidPassword", + "code": 416, + "text": "wf-not-authorized-invalid-password" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -80869,7 +98689,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -80885,14 +98706,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -80904,6 +98727,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -80915,14 +98743,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "request-timeout" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "408" } ], "assertions": [ @@ -80934,6 +98764,11 @@ "kind": "attr", "name": "text", "value": "request-timeout" + }, + { + "kind": "attr", + "name": "code", + "value": "408" } ] }, @@ -80945,14 +98780,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "payload-enc-dec-failed" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "480" } ], "assertions": [ @@ -80964,6 +98801,11 @@ "kind": "attr", "name": "text", "value": "payload-enc-dec-failed" + }, + { + "kind": "attr", + "name": "code", + "value": "480" } ] }, @@ -80975,14 +98817,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -80994,6 +98838,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -81005,14 +98854,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "assertions": [ @@ -81024,6 +98875,11 @@ "kind": "attr", "name": "text", "value": "service-unavailable" + }, + { + "kind": "attr", + "name": "code", + "value": "503" } ] }, @@ -81035,14 +98891,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-authorized" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "401" } ], "assertions": [ @@ -81054,6 +98912,11 @@ "kind": "attr", "name": "text", "value": "not-authorized" + }, + { + "kind": "attr", + "name": "code", + "value": "401" } ] }, @@ -81065,14 +98928,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "rate-overlimit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "429" } ], "assertions": [ @@ -81084,6 +98949,11 @@ "kind": "attr", "name": "text", "value": "rate-overlimit" + }, + { + "kind": "attr", + "name": "code", + "value": "429" } ] }, @@ -81095,14 +98965,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-allowed" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "405" } ], "assertions": [ @@ -81114,6 +98986,11 @@ "kind": "attr", "name": "text", "value": "not-allowed" + }, + { + "kind": "attr", + "name": "code", + "value": "405" } ] }, @@ -81125,14 +99002,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "conflict" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "409" } ], "assertions": [ @@ -81144,6 +99023,11 @@ "kind": "attr", "name": "text", "value": "conflict" + }, + { + "kind": "attr", + "name": "code", + "value": "409" } ] }, @@ -81155,14 +99039,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "already-exists" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "304" } ], "assertions": [ @@ -81174,6 +99060,11 @@ "kind": "attr", "name": "text", "value": "already-exists" + }, + { + "kind": "attr", + "name": "code", + "value": "304" } ] }, @@ -81185,14 +99076,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "wf-not-found" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "483" } ], "assertions": [ @@ -81204,6 +99097,11 @@ "kind": "attr", "name": "text", "value": "wf-not-found" + }, + { + "kind": "attr", + "name": "code", + "value": "483" } ] }, @@ -81215,14 +99113,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "wf-state-mismatch" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "485" } ], "assertions": [ @@ -81234,6 +99134,11 @@ "kind": "attr", "name": "text", "value": "wf-state-mismatch" + }, + { + "kind": "attr", + "name": "code", + "value": "485" } ] }, @@ -81245,14 +99150,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "wf-not-authorized-invalid-password" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "416" } ], "assertions": [ @@ -81264,6 +99171,11 @@ "kind": "attr", "name": "text", "value": "wf-not-authorized-invalid-password" + }, + { + "kind": "attr", + "name": "code", + "value": "416" } ] } @@ -81349,14 +99261,16 @@ "name": "version", "wireName": "version", "type": "string", - "required": true + "required": true, + "literalValue": "1" }, { "method": "attrString", "name": "algorithm", "wireName": "algorithm", "type": "string", - "required": true + "required": true, + "literalValue": "rsa2048" }, { "method": "contentBytes", @@ -81410,7 +99324,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ], "variants": [ @@ -81423,6 +99338,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -81442,14 +99371,16 @@ "name": "version", "wireName": "version", "type": "string", - "required": true + "required": true, + "literalValue": "1" }, { "method": "attrString", "name": "algorithm", "wireName": "algorithm", "type": "string", - "required": true + "required": true, + "literalValue": "rsa2048" }, { "method": "contentBytes", @@ -81503,7 +99434,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ] }, @@ -81511,11 +99443,82 @@ "tag": "GenerateWAEntACUserResponseError", "moduleName": "WASmaxInWaffleGenerateWAEntACUserResponseError", "kind": "error", + "errorArms": [ + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorRequestTimeout", + "code": 408, + "text": "request-timeout" + }, + { + "name": "IQErrorPayloadEncDec", + "code": 480, + "text": "payload-enc-dec-failed" + }, + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorServiceUnavailable", + "code": 503, + "text": "service-unavailable" + }, + { + "name": "IQErrorNotAuthorized", + "code": 401, + "text": "not-authorized" + }, + { + "name": "IQErrorRateOverlimit", + "code": 429, + "text": "rate-overlimit" + }, + { + "name": "IQErrorNotAllowed", + "code": 405, + "text": "not-allowed" + }, + { + "name": "IQErrorConflict", + "code": 409, + "text": "conflict" + }, + { + "name": "IQErrorAlreadyExists", + "code": 304, + "text": "already-exists" + }, + { + "name": "IQErrorWFJurisdictionGating", + "code": 418, + "text": "wf-jurisdiction-gating" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -81528,7 +99531,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -81544,14 +99548,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -81563,6 +99569,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -81574,14 +99585,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "request-timeout" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "408" } ], "assertions": [ @@ -81593,6 +99606,11 @@ "kind": "attr", "name": "text", "value": "request-timeout" + }, + { + "kind": "attr", + "name": "code", + "value": "408" } ] }, @@ -81604,14 +99622,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "payload-enc-dec-failed" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "480" } ], "assertions": [ @@ -81623,6 +99643,11 @@ "kind": "attr", "name": "text", "value": "payload-enc-dec-failed" + }, + { + "kind": "attr", + "name": "code", + "value": "480" } ] }, @@ -81634,14 +99659,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -81653,6 +99680,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -81664,14 +99696,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "assertions": [ @@ -81683,6 +99717,11 @@ "kind": "attr", "name": "text", "value": "service-unavailable" + }, + { + "kind": "attr", + "name": "code", + "value": "503" } ] }, @@ -81694,14 +99733,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-authorized" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "401" } ], "assertions": [ @@ -81713,6 +99754,11 @@ "kind": "attr", "name": "text", "value": "not-authorized" + }, + { + "kind": "attr", + "name": "code", + "value": "401" } ] }, @@ -81724,14 +99770,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "rate-overlimit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "429" } ], "assertions": [ @@ -81743,6 +99791,11 @@ "kind": "attr", "name": "text", "value": "rate-overlimit" + }, + { + "kind": "attr", + "name": "code", + "value": "429" } ] }, @@ -81754,14 +99807,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-allowed" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "405" } ], "assertions": [ @@ -81773,6 +99828,11 @@ "kind": "attr", "name": "text", "value": "not-allowed" + }, + { + "kind": "attr", + "name": "code", + "value": "405" } ] }, @@ -81784,14 +99844,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "conflict" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "409" } ], "assertions": [ @@ -81803,6 +99865,11 @@ "kind": "attr", "name": "text", "value": "conflict" + }, + { + "kind": "attr", + "name": "code", + "value": "409" } ] }, @@ -81814,14 +99881,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "already-exists" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "304" } ], "assertions": [ @@ -81833,6 +99902,11 @@ "kind": "attr", "name": "text", "value": "already-exists" + }, + { + "kind": "attr", + "name": "code", + "value": "304" } ] }, @@ -81844,14 +99918,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "wf-jurisdiction-gating" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "418" } ], "assertions": [ @@ -81863,6 +99939,11 @@ "kind": "attr", "name": "text", "value": "wf-jurisdiction-gating" + }, + { + "kind": "attr", + "name": "code", + "value": "418" } ] } @@ -82021,7 +100102,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ], "variants": [ @@ -82034,6 +100116,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -82145,7 +100241,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ] }, @@ -82153,11 +100250,62 @@ "tag": "GetCertificateResponseError", "moduleName": "WASmaxInWaffleGetCertificateResponseError", "kind": "error", + "errorArms": [ + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorRequestTimeout", + "code": 408, + "text": "request-timeout" + }, + { + "name": "IQErrorNotAllowed", + "code": 405, + "text": "not-allowed" + }, + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorRateOverlimit", + "code": 429, + "text": "rate-overlimit" + }, + { + "name": "IQErrorServiceUnavailable", + "code": 503, + "text": "service-unavailable" + }, + { + "name": "IQErrorFeatureNotImplemented", + "code": 501, + "text": "feature-not-implemented" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -82170,7 +100318,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -82186,14 +100335,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -82205,6 +100356,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -82216,14 +100372,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "request-timeout" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "408" } ], "assertions": [ @@ -82235,6 +100393,11 @@ "kind": "attr", "name": "text", "value": "request-timeout" + }, + { + "kind": "attr", + "name": "code", + "value": "408" } ] }, @@ -82246,14 +100409,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-allowed" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "405" } ], "assertions": [ @@ -82265,6 +100430,11 @@ "kind": "attr", "name": "text", "value": "not-allowed" + }, + { + "kind": "attr", + "name": "code", + "value": "405" } ] }, @@ -82276,14 +100446,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -82295,6 +100467,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -82306,14 +100483,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "rate-overlimit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "429" } ], "assertions": [ @@ -82325,6 +100504,11 @@ "kind": "attr", "name": "text", "value": "rate-overlimit" + }, + { + "kind": "attr", + "name": "code", + "value": "429" } ] }, @@ -82336,14 +100520,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "assertions": [ @@ -82355,6 +100541,11 @@ "kind": "attr", "name": "text", "value": "service-unavailable" + }, + { + "kind": "attr", + "name": "code", + "value": "503" } ] }, @@ -82366,14 +100557,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "feature-not-implemented" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "501" } ], "assertions": [ @@ -82385,6 +100578,11 @@ "kind": "attr", "name": "text", "value": "feature-not-implemented" + }, + { + "kind": "attr", + "name": "code", + "value": "501" } ] } @@ -82449,14 +100647,16 @@ "name": "version", "wireName": "version", "type": "string", - "required": true + "required": true, + "literalValue": "1" }, { "method": "attrString", "name": "algorithm", "wireName": "algorithm", "type": "string", - "required": true + "required": true, + "literalValue": "rsa2048" }, { "method": "contentBytes", @@ -82510,7 +100710,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ], "variants": [ @@ -82523,6 +100724,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -82542,14 +100757,16 @@ "name": "version", "wireName": "version", "type": "string", - "required": true + "required": true, + "literalValue": "1" }, { "method": "attrString", "name": "algorithm", "wireName": "algorithm", "type": "string", - "required": true + "required": true, + "literalValue": "rsa2048" }, { "method": "contentBytes", @@ -82603,7 +100820,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ] }, @@ -82611,11 +100829,92 @@ "tag": "RefreshAccessTokensResponseError", "moduleName": "WASmaxInWaffleRefreshAccessTokensResponseError", "kind": "error", + "errorArms": [ + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorRequestTimeout", + "code": 408, + "text": "request-timeout" + }, + { + "name": "IQErrorPayloadEncDec", + "code": 480, + "text": "payload-enc-dec-failed" + }, + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorServiceUnavailable", + "code": 503, + "text": "service-unavailable" + }, + { + "name": "IQErrorNotAuthorized", + "code": 401, + "text": "not-authorized" + }, + { + "name": "IQErrorRateOverlimit", + "code": 429, + "text": "rate-overlimit" + }, + { + "name": "IQErrorNotAllowed", + "code": 405, + "text": "not-allowed" + }, + { + "name": "IQErrorConflict", + "code": 409, + "text": "conflict" + }, + { + "name": "IQErrorWFNotFound", + "code": 483, + "text": "wf-not-found" + }, + { + "name": "IQErrorWFSuspended", + "code": 484, + "text": "wf-suspended" + }, + { + "name": "IQErrorWFStateMismatch", + "code": 485, + "text": "wf-state-mismatch" + }, + { + "name": "IQErrorWFNotAuthorizedInvalidPassword", + "code": 416, + "text": "wf-not-authorized-invalid-password" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -82628,7 +100927,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -82644,14 +100944,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -82663,6 +100965,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -82674,14 +100981,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "request-timeout" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "408" } ], "assertions": [ @@ -82693,6 +101002,11 @@ "kind": "attr", "name": "text", "value": "request-timeout" + }, + { + "kind": "attr", + "name": "code", + "value": "408" } ] }, @@ -82704,14 +101018,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "payload-enc-dec-failed" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "480" } ], "assertions": [ @@ -82723,6 +101039,11 @@ "kind": "attr", "name": "text", "value": "payload-enc-dec-failed" + }, + { + "kind": "attr", + "name": "code", + "value": "480" } ] }, @@ -82734,14 +101055,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -82753,6 +101076,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -82764,14 +101092,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "assertions": [ @@ -82783,6 +101113,11 @@ "kind": "attr", "name": "text", "value": "service-unavailable" + }, + { + "kind": "attr", + "name": "code", + "value": "503" } ] }, @@ -82794,14 +101129,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-authorized" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "401" } ], "assertions": [ @@ -82813,6 +101150,11 @@ "kind": "attr", "name": "text", "value": "not-authorized" + }, + { + "kind": "attr", + "name": "code", + "value": "401" } ] }, @@ -82824,14 +101166,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "rate-overlimit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "429" } ], "assertions": [ @@ -82843,6 +101187,11 @@ "kind": "attr", "name": "text", "value": "rate-overlimit" + }, + { + "kind": "attr", + "name": "code", + "value": "429" } ] }, @@ -82854,14 +101203,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-allowed" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "405" } ], "assertions": [ @@ -82873,6 +101224,11 @@ "kind": "attr", "name": "text", "value": "not-allowed" + }, + { + "kind": "attr", + "name": "code", + "value": "405" } ] }, @@ -82884,14 +101240,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "conflict" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "409" } ], "assertions": [ @@ -82903,6 +101261,11 @@ "kind": "attr", "name": "text", "value": "conflict" + }, + { + "kind": "attr", + "name": "code", + "value": "409" } ] }, @@ -82914,14 +101277,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "wf-not-found" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "483" } ], "assertions": [ @@ -82933,6 +101298,11 @@ "kind": "attr", "name": "text", "value": "wf-not-found" + }, + { + "kind": "attr", + "name": "code", + "value": "483" } ] }, @@ -82944,28 +101314,58 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "wf-suspended" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "484" }, { "method": "maybeAttrEnum", "name": "ndc", "wireName": "ndc", "type": "enum", - "required": false + "required": false, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInWaffleEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + } }, { "method": "maybeAttrEnum", "name": "npr", "wireName": "npr", "type": "enum", - "required": false + "required": false, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInWaffleEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + } } ], "assertions": [ @@ -82977,6 +101377,11 @@ "kind": "attr", "name": "text", "value": "wf-suspended" + }, + { + "kind": "attr", + "name": "code", + "value": "484" } ] }, @@ -82988,14 +101393,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "wf-state-mismatch" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "485" } ], "assertions": [ @@ -83007,6 +101414,11 @@ "kind": "attr", "name": "text", "value": "wf-state-mismatch" + }, + { + "kind": "attr", + "name": "code", + "value": "485" } ] }, @@ -83018,14 +101430,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "wf-not-authorized-invalid-password" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "416" } ], "assertions": [ @@ -83037,6 +101451,11 @@ "kind": "attr", "name": "text", "value": "wf-not-authorized-invalid-password" + }, + { + "kind": "attr", + "name": "code", + "value": "416" } ] } @@ -83091,7 +101510,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "child", @@ -83105,7 +101525,21 @@ "name": "npr", "wireName": "npr", "type": "enum", - "required": false + "required": false, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInWaffleEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + } } ], "repeats": false @@ -83121,6 +101555,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -83142,7 +101590,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" }, { "method": "child", @@ -83156,7 +101605,21 @@ "name": "npr", "wireName": "npr", "type": "enum", - "required": false + "required": false, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInWaffleEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + } } ], "repeats": false @@ -83167,11 +101630,57 @@ "tag": "StateExistsResponseError", "moduleName": "WASmaxInWaffleStateExistsResponseError", "kind": "error", + "errorArms": [ + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorRequestTimeout", + "code": 408, + "text": "request-timeout" + }, + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorServiceUnavailable", + "code": 503, + "text": "service-unavailable" + }, + { + "name": "IQErrorRateOverlimit", + "code": 429, + "text": "rate-overlimit" + }, + { + "name": "IQErrorNotAllowed", + "code": 405, + "text": "not-allowed" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -83184,7 +101693,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -83200,14 +101710,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -83219,6 +101731,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -83230,14 +101747,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "request-timeout" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "408" } ], "assertions": [ @@ -83249,6 +101768,11 @@ "kind": "attr", "name": "text", "value": "request-timeout" + }, + { + "kind": "attr", + "name": "code", + "value": "408" } ] }, @@ -83260,14 +101784,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -83279,6 +101805,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -83290,14 +101821,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "assertions": [ @@ -83309,6 +101842,11 @@ "kind": "attr", "name": "text", "value": "service-unavailable" + }, + { + "kind": "attr", + "name": "code", + "value": "503" } ] }, @@ -83320,14 +101858,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "rate-overlimit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "429" } ], "assertions": [ @@ -83339,6 +101879,11 @@ "kind": "attr", "name": "text", "value": "rate-overlimit" + }, + { + "kind": "attr", + "name": "code", + "value": "429" } ] }, @@ -83350,14 +101895,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-allowed" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "405" } ], "assertions": [ @@ -83369,6 +101916,11 @@ "kind": "attr", "name": "text", "value": "not-allowed" + }, + { + "kind": "attr", + "name": "code", + "value": "405" } ] } @@ -83435,7 +101987,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ], "variants": [ @@ -83448,6 +102001,20 @@ "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -83469,7 +102036,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "result" } ] }, @@ -83477,11 +102045,87 @@ "tag": "WFPingResponseError", "moduleName": "WASmaxInWaffleWFPingResponseError", "kind": "error", + "errorArms": [ + { + "name": "IQErrorBadRequest", + "code": 400, + "text": "bad-request" + }, + { + "name": "IQErrorRequestTimeout", + "code": 408, + "text": "request-timeout" + }, + { + "name": "IQErrorPayloadEncDec", + "code": 480, + "text": "payload-enc-dec-failed" + }, + { + "name": "IQErrorInternalServerError", + "code": 500, + "text": "internal-server-error" + }, + { + "name": "IQErrorServiceUnavailable", + "code": 503, + "text": "service-unavailable" + }, + { + "name": "IQErrorNotAuthorized", + "code": 401, + "text": "not-authorized" + }, + { + "name": "IQErrorRateOverlimit", + "code": 429, + "text": "rate-overlimit" + }, + { + "name": "IQErrorNotAllowed", + "code": 405, + "text": "not-allowed" + }, + { + "name": "IQErrorConflict", + "code": 409, + "text": "conflict" + }, + { + "name": "IQErrorWFNotFound", + "code": 483, + "text": "wf-not-found" + }, + { + "name": "IQErrorWFSuspended", + "code": 484, + "text": "wf-suspended" + }, + { + "name": "IQErrorWFStateMismatch", + "code": 485, + "text": "wf-state-mismatch" + } + ], "assertions": [ { "kind": "tag", "name": "iq" }, + { + "kind": "reference", + "name": "id", + "referencePath": [ + "id" + ] + }, + { + "kind": "reference", + "name": "from", + "referencePath": [ + "to" + ] + }, { "kind": "attr", "name": "type", @@ -83494,7 +102138,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "error" }, { "method": "", @@ -83510,14 +102155,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "bad-request" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "400" } ], "assertions": [ @@ -83529,6 +102176,11 @@ "kind": "attr", "name": "text", "value": "bad-request" + }, + { + "kind": "attr", + "name": "code", + "value": "400" } ] }, @@ -83540,14 +102192,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "request-timeout" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "408" } ], "assertions": [ @@ -83559,6 +102213,11 @@ "kind": "attr", "name": "text", "value": "request-timeout" + }, + { + "kind": "attr", + "name": "code", + "value": "408" } ] }, @@ -83570,14 +102229,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "payload-enc-dec-failed" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "480" } ], "assertions": [ @@ -83589,6 +102250,11 @@ "kind": "attr", "name": "text", "value": "payload-enc-dec-failed" + }, + { + "kind": "attr", + "name": "code", + "value": "480" } ] }, @@ -83600,14 +102266,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "internal-server-error" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "500" } ], "assertions": [ @@ -83619,6 +102287,11 @@ "kind": "attr", "name": "text", "value": "internal-server-error" + }, + { + "kind": "attr", + "name": "code", + "value": "500" } ] }, @@ -83630,14 +102303,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "service-unavailable" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "503" } ], "assertions": [ @@ -83649,6 +102324,11 @@ "kind": "attr", "name": "text", "value": "service-unavailable" + }, + { + "kind": "attr", + "name": "code", + "value": "503" } ] }, @@ -83660,14 +102340,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-authorized" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "401" } ], "assertions": [ @@ -83679,6 +102361,11 @@ "kind": "attr", "name": "text", "value": "not-authorized" + }, + { + "kind": "attr", + "name": "code", + "value": "401" } ] }, @@ -83690,14 +102377,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "rate-overlimit" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "429" } ], "assertions": [ @@ -83709,6 +102398,11 @@ "kind": "attr", "name": "text", "value": "rate-overlimit" + }, + { + "kind": "attr", + "name": "code", + "value": "429" } ] }, @@ -83720,14 +102414,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "not-allowed" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "405" } ], "assertions": [ @@ -83739,6 +102435,11 @@ "kind": "attr", "name": "text", "value": "not-allowed" + }, + { + "kind": "attr", + "name": "code", + "value": "405" } ] }, @@ -83750,14 +102451,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "conflict" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "409" } ], "assertions": [ @@ -83769,6 +102472,11 @@ "kind": "attr", "name": "text", "value": "conflict" + }, + { + "kind": "attr", + "name": "code", + "value": "409" } ] }, @@ -83780,14 +102488,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "wf-not-found" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "483" } ], "assertions": [ @@ -83799,6 +102509,11 @@ "kind": "attr", "name": "text", "value": "wf-not-found" + }, + { + "kind": "attr", + "name": "code", + "value": "483" } ] }, @@ -83810,28 +102525,58 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "wf-suspended" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "484" }, { "method": "maybeAttrEnum", "name": "ndc", "wireName": "ndc", "type": "enum", - "required": false + "required": false, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInWaffleEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + } }, { "method": "maybeAttrEnum", "name": "npr", "wireName": "npr", "type": "enum", - "required": false + "required": false, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInWaffleEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + } } ], "assertions": [ @@ -83843,6 +102588,11 @@ "kind": "attr", "name": "text", "value": "wf-suspended" + }, + { + "kind": "attr", + "name": "code", + "value": "484" } ] }, @@ -83854,14 +102604,16 @@ "name": "text", "wireName": "text", "type": "string", - "required": true + "required": true, + "literalValue": "wf-state-mismatch" }, { "method": "attrInt", "name": "code", "wireName": "code", "type": "integer", - "required": true + "required": true, + "literalValue": "485" } ], "assertions": [ @@ -83873,6 +102625,11 @@ "kind": "attr", "name": "text", "value": "wf-state-mismatch" + }, + { + "kind": "attr", + "name": "code", + "value": "485" } ] } diff --git a/generated/manifest.json b/generated/manifest.json index 7b3e2ec..80ea840 100644 --- a/generated/manifest.json +++ b/generated/manifest.json @@ -2,8 +2,21 @@ "abPropsConfigs": 2483, "appstateActions": 67, "diagnostics": { + "incoming": { + "dropsByReason": { + "response enum argument not structurally resolvable": 1 + } + }, "iq": { "candidateModules": 207, + "constraints": { + "errorArms": 645, + "errorTexts": 577, + "fieldEnumRefs": 151, + "fieldLiterals": 1784, + "referenceConstraints": 584, + "typedErrorVariants": 104 + }, "crossModule": { "fieldsRecovered": 88, "requestsEnriched": 11, @@ -12,7 +25,8 @@ "degradedResponses": 4, "dropsByReason": { "iq builder substring present but no AST iq call": 5, - "mixin fragment (folded into requests, not a standalone stanza)": 66 + "mixin fragment (folded into requests, not a standalone stanza)": 66, + "response enum argument not structurally resolvable": 41 }, "excludedFragments": 66, "stanzas": 143, @@ -20,7 +34,12 @@ "unparseable": 5 }, "notif": { + "actionShapes": 184, + "actions": 47, "degraded": 5, + "dropsByReason": { + "action enum table not structurally resolvable": 1 + }, "stanzaTags": 13, "typedContent": 22, "types": 27 @@ -30,37 +49,37 @@ "abprops": { "file": "abprops/index.json", "schema": "schema/abprops.schema.json", - "sha256": "efa3cb733c8533fc1910f7f93fa52288e3368b1b55599fe96b647fa75eedc885" + "sha256": "aad4063a4e83ec6f7ce7f57f3e13dca9e06c7afe76e93ef97a1c3e7dc6f8df60" }, "appstate": { "file": "appstate/index.json", "schema": "schema/appstate.schema.json", - "sha256": "ed9e161621be8eaaa75787a1365a06dfe435ceea5218fdcafc18ce26082f8593" + "sha256": "9f5ec14ac8c3a154890539bdc2f8ed2644867be77089ede6f20165ac0e01e7d2" }, "enums": { "file": "enums/index.json", "schema": "schema/enums.schema.json", - "sha256": "af2c1bc1f6afa9d33c0b8ccbfb14142b00c0c0f35ec4a7ba93a9a577b9b9277d" + "sha256": "a8aee81f035167ab5da601bb1f8caad8b2978707ed1875a4113c1935cec8f050" }, "incoming": { "file": "incoming/index.json", "schema": "schema/incoming.schema.json", - "sha256": "3c1aa63a212cb3e7d08842b62bf10b88aa9bfa7fb3ca7ee3a9fa62b94a1d4957" + "sha256": "5b25ff40ada72c298e17d8f8826c131b51b3c9d166e234dbb43f70647448d99b" }, "iq": { "file": "iq/index.json", "schema": "schema/iq.schema.json", - "sha256": "4792a9a6e438a47948f536bd43364ceb0ffc64b553d7ff76b399691053ba4013" + "sha256": "455d2a98f9e9ead8311bd8b5fc2cbadfabf6247ce699b5fa5d36f3bb796b3a28" }, "mex": { "file": "mex/index.json", "schema": "schema/mex.schema.json", - "sha256": "00b50b4edd26b1f3b64b47a83da460cd571cabae2bd7f9e8dd225db1fc42ba66" + "sha256": "c3f1927f43b5ed47ed5354a30f4caddc1aa18b702852c789a5e2c722a927232d" }, "notif": { "file": "notif/index.json", "schema": "schema/notif.schema.json", - "sha256": "08eab8e81dcc2c8ac0739ef0f050c5b6ca6860dca786f1af1a4dfdd8526b64d2" + "sha256": "473f4d20fefe3136b264f3398811fb9af85dc5fca59022b727ca16f83420cd33" }, "proto": { "file": "proto/WAProto.proto", @@ -69,27 +88,27 @@ "srvreq": { "file": "srvreq/index.json", "schema": "schema/srvreq.schema.json", - "sha256": "4529564d4e68070c2a6dd9d872550b1233d3ab7a80d1a346b3a0374d8413be63" + "sha256": "35bda50a8a1924274ff1e5be0a21ef189fa605378150b44b64ad7b41426ed48e" }, "stanza": { "file": "stanza/index.json", "schema": "schema/stanza.schema.json", - "sha256": "ab2e7bc4584b524aafdd70fd9c0aa18701347b722b77ae3262c74c5debdd0298" + "sha256": "0245cee882b580cb75af339dd3a128c76bd3cc34960be31081593999ef02b8b7" }, "tokens": { "file": "tokens/index.json", "schema": "schema/tokens.schema.json", - "sha256": "d0ab67e3f17f152f65785c617e9e854dc1488ba019423b4b44854681d1ac76fd" + "sha256": "d2ab9a3ebbb0a046e93fb2d01d6df6aca306042e6ad665f0b366c370865dac24" }, "wam": { "file": "wam/index.json", "schema": "schema/wam.schema.json", - "sha256": "aa673facefa5a0c6e61a946f3e83e4daaa3c5a0c405bda25acc15daf0792a531" + "sha256": "935227cad7e239bcf5a239cf67619b3c43584acd6cba5f516ba1c298670d6d40" }, "wasm": { "file": "wasm/index.json", "schema": "schema/wasm.schema.json", - "sha256": "da85bc11e4d5a7f47d1c65250780c02565f256888dac047fd817f5f9e4174f7a" + "sha256": "362157f1e1e59cecbd4e89c9eb4f2cc1465c81ab8718fddded80d8fccb3a2713" } }, "enumDefs": 326, @@ -99,7 +118,7 @@ "mexOperations": 134, "notifTypes": 27, "protoEntities": 264, - "schemaVersion": "1.0.0", + "schemaVersion": "2.0.0", "serverRequestDefs": 22, "stanzaDefs": 176, "tokenDoubleByte": 1024, diff --git a/generated/mex/index.json b/generated/mex/index.json index d502e47..0f4f0fc 100644 --- a/generated/mex/index.json +++ b/generated/mex/index.json @@ -1,5 +1,5 @@ { - "schemaVersion": "1.0.0", + "schemaVersion": "2.0.0", "waVersion": "2.3000.1043899084", "operations": { "ACSServerProviderConfig": { diff --git a/generated/notif/index.json b/generated/notif/index.json index bbe34e3..2616b04 100644 --- a/generated/notif/index.json +++ b/generated/notif/index.json @@ -1,5 +1,5 @@ { - "schemaVersion": "1.0.0", + "schemaVersion": "2.0.0", "waVersion": "2.3000.1043899084", "dispatcherModules": [ "WAWebCommsHandleLoggedInStanza", @@ -641,10 +641,11 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "crsc_continuation" }, { - "method": "attrJidWithType", + "method": "literalJid", "name": "from", "wireName": "from", "type": "jid", @@ -1062,10 +1063,11 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "passkey_prologue_request" }, { - "method": "attrJidWithType", + "method": "literalJid", "name": "from", "wireName": "from", "type": "jid", @@ -1338,8 +1340,13 @@ { "method": "attrEnumValues", "name": "mediatype", - "type": "string", - "required": true + "type": "enum", + "required": true, + "enumKeys": [ + "image", + "video", + "text" + ] }, { "method": "contentBytes", @@ -1371,8 +1378,13 @@ { "method": "attrEnumValues", "name": "mediatype", - "type": "string", - "required": true + "type": "enum", + "required": true, + "enumKeys": [ + "image", + "video", + "text" + ] }, { "method": "contentBytes", @@ -1599,6 +1611,12 @@ "type": "user_jid", "required": true }, + { + "method": "maybeAttrPhoneUserJid", + "name": "participant_pn", + "type": "user_jid", + "required": false + }, { "method": "attrTime", "name": "t", @@ -1738,7 +1756,1109 @@ "required": false } ] - } + }, + "actions": [ + { + "wireTag": "create", + "actionType": "create", + "fields": [ + { + "name": "reason", + "wireName": "reason", + "type": "enum", + "required": false + }, + { + "name": "contextGroupId", + "wireName": "context_group_jid", + "type": "group_jid", + "required": false + } + ] + }, + { + "wireTag": "add", + "actionType": "add", + "fields": [ + { + "name": "reason", + "wireName": "reason", + "type": "string", + "required": false + } + ], + "children": [ + { + "name": "participants", + "wireTag": "participant", + "fields": [ + { + "name": "displayName", + "wireName": "display_name", + "type": "string", + "required": false + }, + { + "name": "id", + "wireName": "jid", + "type": "user_jid", + "required": true + }, + { + "name": "lid", + "wireName": "lid", + "type": "lid_user_jid", + "required": false + }, + { + "name": "phoneNumber", + "wireName": "phone_number", + "type": "user_jid", + "required": false + }, + { + "name": "username", + "wireName": "username", + "type": "string", + "required": false + }, + { + "name": "joinTime", + "wireName": "join_time", + "type": "integer", + "required": false + }, + { + "name": "groupHistorySentState", + "wireName": "group_history_sent_state", + "type": "string", + "required": false + } + ] + } + ] + }, + { + "wireTag": "delete", + "actionType": "delete", + "fields": [ + { + "name": "reason", + "wireName": "reason", + "type": "string", + "required": false + } + ] + }, + { + "wireTag": "remove", + "actionType": "remove", + "fields": [ + { + "name": "reason", + "wireName": "reason", + "type": "string", + "required": false + } + ], + "children": [ + { + "name": "participants", + "wireTag": "participant", + "fields": [ + { + "name": "displayName", + "wireName": "display_name", + "type": "string", + "required": false + }, + { + "name": "id", + "wireName": "jid", + "type": "user_jid", + "required": true + }, + { + "name": "lid", + "wireName": "lid", + "type": "lid_user_jid", + "required": false + }, + { + "name": "phoneNumber", + "wireName": "phone_number", + "type": "user_jid", + "required": false + }, + { + "name": "username", + "wireName": "username", + "type": "string", + "required": false + }, + { + "name": "joinTime", + "wireName": "join_time", + "type": "integer", + "required": false + }, + { + "name": "groupHistorySentState", + "wireName": "group_history_sent_state", + "type": "string", + "required": false + } + ] + } + ] + }, + { + "wireTag": "promote", + "actionType": "promote", + "children": [ + { + "name": "participants", + "wireTag": "participant", + "fields": [ + { + "name": "displayName", + "wireName": "display_name", + "type": "string", + "required": false + }, + { + "name": "id", + "wireName": "jid", + "type": "user_jid", + "required": true + }, + { + "name": "lid", + "wireName": "lid", + "type": "lid_user_jid", + "required": false + }, + { + "name": "phoneNumber", + "wireName": "phone_number", + "type": "user_jid", + "required": false + }, + { + "name": "username", + "wireName": "username", + "type": "string", + "required": false + }, + { + "name": "joinTime", + "wireName": "join_time", + "type": "integer", + "required": false + }, + { + "name": "groupHistorySentState", + "wireName": "group_history_sent_state", + "type": "string", + "required": false + } + ] + } + ] + }, + { + "wireTag": "demote", + "actionType": "demote", + "children": [ + { + "name": "participants", + "wireTag": "participant", + "fields": [ + { + "name": "displayName", + "wireName": "display_name", + "type": "string", + "required": false + }, + { + "name": "id", + "wireName": "jid", + "type": "user_jid", + "required": true + }, + { + "name": "lid", + "wireName": "lid", + "type": "lid_user_jid", + "required": false + }, + { + "name": "phoneNumber", + "wireName": "phone_number", + "type": "user_jid", + "required": false + }, + { + "name": "username", + "wireName": "username", + "type": "string", + "required": false + }, + { + "name": "joinTime", + "wireName": "join_time", + "type": "integer", + "required": false + }, + { + "name": "groupHistorySentState", + "wireName": "group_history_sent_state", + "type": "string", + "required": false + } + ] + } + ] + }, + { + "wireTag": "linked_group_promote", + "actionType": "linked_group_promote", + "fields": [ + { + "name": "jid", + "wireName": "jid", + "type": "group_jid", + "required": false + } + ], + "children": [ + { + "name": "participants", + "wireTag": "participant", + "fields": [ + { + "name": "displayName", + "wireName": "display_name", + "type": "string", + "required": false + }, + { + "name": "id", + "wireName": "jid", + "type": "user_jid", + "required": true + }, + { + "name": "lid", + "wireName": "lid", + "type": "lid_user_jid", + "required": false + }, + { + "name": "phoneNumber", + "wireName": "phone_number", + "type": "user_jid", + "required": false + }, + { + "name": "username", + "wireName": "username", + "type": "string", + "required": false + }, + { + "name": "joinTime", + "wireName": "join_time", + "type": "integer", + "required": false + }, + { + "name": "groupHistorySentState", + "wireName": "group_history_sent_state", + "type": "string", + "required": false + } + ] + } + ] + }, + { + "wireTag": "linked_group_demote", + "actionType": "linked_group_demote", + "fields": [ + { + "name": "jid", + "wireName": "jid", + "type": "group_jid", + "required": false + } + ], + "children": [ + { + "name": "participants", + "wireTag": "participant", + "fields": [ + { + "name": "displayName", + "wireName": "display_name", + "type": "string", + "required": false + }, + { + "name": "id", + "wireName": "jid", + "type": "user_jid", + "required": true + }, + { + "name": "lid", + "wireName": "lid", + "type": "lid_user_jid", + "required": false + }, + { + "name": "phoneNumber", + "wireName": "phone_number", + "type": "user_jid", + "required": false + }, + { + "name": "username", + "wireName": "username", + "type": "string", + "required": false + }, + { + "name": "joinTime", + "wireName": "join_time", + "type": "integer", + "required": false + }, + { + "name": "groupHistorySentState", + "wireName": "group_history_sent_state", + "type": "string", + "required": false + } + ] + } + ] + }, + { + "wireTag": "modify", + "actionType": "modify", + "children": [ + { + "name": "participants", + "wireTag": "participant", + "fields": [ + { + "name": "displayName", + "wireName": "display_name", + "type": "string", + "required": false + }, + { + "name": "id", + "wireName": "jid", + "type": "user_jid", + "required": true + }, + { + "name": "lid", + "wireName": "lid", + "type": "lid_user_jid", + "required": false + }, + { + "name": "phoneNumber", + "wireName": "phone_number", + "type": "user_jid", + "required": false + }, + { + "name": "username", + "wireName": "username", + "type": "string", + "required": false + }, + { + "name": "joinTime", + "wireName": "join_time", + "type": "integer", + "required": false + }, + { + "name": "groupHistorySentState", + "wireName": "group_history_sent_state", + "type": "string", + "required": false + } + ] + } + ] + }, + { + "wireTag": "subject", + "actionType": "subject", + "fields": [ + { + "name": "subject", + "wireName": "subject", + "type": "string", + "required": true + }, + { + "name": "s_o", + "wireName": "s_o", + "type": "user_jid", + "required": false + }, + { + "name": "subjectOwnerPn", + "wireName": "s_o_pn", + "type": "user_jid", + "required": false + }, + { + "name": "subjectOwnerUsername", + "wireName": "s_o_username", + "type": "string", + "required": false + }, + { + "name": "s_t", + "wireName": "s_t", + "type": "integer", + "required": false + } + ] + }, + { + "wireTag": "description", + "actionType": "desc_remove", + "fields": [ + { + "name": "descId", + "wireName": "id", + "type": "string", + "required": true + } + ] + }, + { + "wireTag": "description", + "actionType": "desc_add", + "fields": [ + { + "name": "descId", + "wireName": "id", + "type": "string", + "required": true + }, + { + "name": "desc", + "wireName": "body", + "type": "string", + "required": false, + "content": true + } + ] + }, + { + "wireTag": "suspended", + "actionType": "suspend", + "constantFields": [ + { + "name": "value", + "value": true + } + ] + }, + { + "wireTag": "unsuspended", + "actionType": "suspend", + "constantFields": [ + { + "name": "value", + "value": false + } + ] + }, + { + "wireTag": "locked", + "actionType": "restrict", + "fields": [ + { + "name": "threshold", + "wireName": "threshold", + "type": "string", + "required": false + } + ], + "constantFields": [ + { + "name": "value", + "value": true + } + ] + }, + { + "wireTag": "unlocked", + "actionType": "restrict", + "constantFields": [ + { + "name": "value", + "value": false + } + ] + }, + { + "wireTag": "announcement", + "actionType": "announce", + "constantFields": [ + { + "name": "value", + "value": true + } + ] + }, + { + "wireTag": "not_announcement", + "actionType": "announce", + "constantFields": [ + { + "name": "value", + "value": false + } + ] + }, + { + "wireTag": "no_frequently_forwarded", + "actionType": "no_frequently_forwarded", + "constantFields": [ + { + "name": "value", + "value": true + } + ] + }, + { + "wireTag": "frequently_forwarded_ok", + "actionType": "no_frequently_forwarded", + "constantFields": [ + { + "name": "value", + "value": false + } + ] + }, + { + "wireTag": "invite", + "actionType": "invite", + "fields": [ + { + "name": "code", + "wireName": "code", + "type": "string", + "required": true + } + ] + }, + { + "wireTag": "ephemeral", + "actionType": "ephemeral", + "fields": [ + { + "name": "duration", + "wireName": "expiration", + "type": "integer", + "required": true + }, + { + "name": "trigger", + "wireName": "trigger", + "type": "integer", + "required": false + } + ] + }, + { + "wireTag": "not_ephemeral", + "actionType": "ephemeral", + "constantFields": [ + { + "name": "duration", + "value": 0 + } + ] + }, + { + "wireTag": "revoke", + "actionType": "revoke_invite", + "children": [ + { + "name": "participants", + "wireTag": "participant", + "fields": [ + { + "name": "id", + "wireName": "jid", + "type": "user_jid", + "required": true + }, + { + "name": "expiration", + "wireName": "expiration", + "type": "integer", + "required": true + } + ] + } + ] + }, + { + "wireTag": "growth_unlocked", + "actionType": "growth_unlocked" + }, + { + "wireTag": "growth_locked", + "actionType": "growth_locked", + "fields": [ + { + "name": "expiration", + "wireName": "expiration", + "type": "integer", + "required": true + }, + { + "name": "type", + "wireName": "type", + "type": "string", + "required": true + } + ] + }, + { + "wireTag": "link", + "children": [ + { + "name": "groupDatas", + "wireTag": "group", + "fields": [ + { + "name": "id", + "wireName": "jid", + "type": "group_jid", + "required": true + }, + { + "name": "subject", + "wireName": "subject", + "type": "string", + "required": true + }, + { + "name": "subjectTime", + "wireName": "s_t", + "type": "integer", + "required": true + } + ] + } + ] + }, + { + "wireTag": "unlink", + "actionType": "delete_parent_group_unlink", + "children": [ + { + "name": "groupDatas", + "wireTag": "group", + "fields": [ + { + "name": "id", + "wireName": "jid", + "type": "group_jid", + "required": true + }, + { + "name": "subject", + "wireName": "subject", + "type": "string", + "required": true + }, + { + "name": "subjectTime", + "wireName": "s_t", + "type": "integer", + "required": true + } + ] + } + ] + }, + { + "wireTag": "unlink", + "actionType": "integrity_parent_group_unlink", + "children": [ + { + "name": "groupDatas", + "wireTag": "group", + "fields": [ + { + "name": "id", + "wireName": "jid", + "type": "group_jid", + "required": true + }, + { + "name": "subject", + "wireName": "subject", + "type": "string", + "required": true + }, + { + "name": "subjectTime", + "wireName": "s_t", + "type": "integer", + "required": true + } + ] + } + ] + }, + { + "wireTag": "unlink", + "actionType": "integrity_sub_group_unlink", + "children": [ + { + "name": "groupDatas", + "wireTag": "group", + "fields": [ + { + "name": "id", + "wireName": "jid", + "type": "group_jid", + "required": true + }, + { + "name": "subject", + "wireName": "subject", + "type": "string", + "required": true + }, + { + "name": "subjectTime", + "wireName": "s_t", + "type": "integer", + "required": true + } + ] + } + ] + }, + { + "wireTag": "unlink", + "children": [ + { + "name": "groupDatas", + "wireTag": "group", + "fields": [ + { + "name": "id", + "wireName": "jid", + "type": "group_jid", + "required": true + }, + { + "name": "subject", + "wireName": "subject", + "type": "string", + "required": true + }, + { + "name": "subjectTime", + "wireName": "s_t", + "type": "integer", + "required": true + } + ] + } + ] + }, + { + "wireTag": "membership_approval_mode", + "actionType": "membership_approval_mode", + "fields": [ + { + "name": "triggered", + "wireName": "triggered", + "type": "string", + "required": false + } + ] + }, + { + "wireTag": "membership_approval_request", + "actionType": "membership_approval_request", + "fields": [ + { + "name": "parentGroupId", + "wireName": "parent_group_jid", + "type": "group_jid", + "required": false + } + ] + }, + { + "wireTag": "allow_admin_reports", + "actionType": "allow_admin_reports", + "fields": [ + { + "name": "triggered", + "wireName": "triggered", + "type": "string", + "required": false + } + ], + "constantFields": [ + { + "name": "shouldSkipGenMsg", + "value": false + }, + { + "name": "value", + "value": true + } + ] + }, + { + "wireTag": "not_allow_admin_reports", + "actionType": "allow_admin_reports", + "fields": [ + { + "name": "triggered", + "wireName": "triggered", + "type": "string", + "required": false + } + ], + "constantFields": [ + { + "name": "shouldSkipGenMsg", + "value": false + }, + { + "name": "value", + "value": false + } + ] + }, + { + "wireTag": "reports", + "actionType": "admin_report_received", + "constantFields": [ + { + "name": "shouldSkipGenMsg", + "value": true + } + ] + }, + { + "wireTag": "created_membership_requests", + "actionType": "created_membership_requests", + "fields": [ + { + "name": "parentGroupId", + "wireName": "parent_group_jid", + "type": "group_jid", + "required": false + } + ], + "children": [ + { + "name": "requests", + "wireTag": "requested_user", + "fields": [ + { + "name": "wid", + "wireName": "jid", + "type": "user_jid", + "required": true + }, + { + "name": "username", + "wireName": "username", + "type": "string", + "required": false + }, + { + "name": "phoneNumber", + "wireName": "phone_number", + "type": "user_jid", + "required": false + } + ] + } + ] + }, + { + "wireTag": "revoked_membership_requests", + "actionType": "revoked_membership_requests", + "children": [ + { + "name": "requests", + "wireTag": "participant", + "fields": [ + { + "name": "jid", + "wireName": "jid", + "type": "user_jid", + "required": true + } + ] + } + ] + }, + { + "wireTag": "allow_non_admin_sub_group_creation", + "actionType": "allow_non_admin_sub_group_creation", + "constantFields": [ + { + "name": "value", + "value": true + } + ] + }, + { + "wireTag": "not_allow_non_admin_sub_group_creation", + "actionType": "allow_non_admin_sub_group_creation", + "constantFields": [ + { + "name": "value", + "value": false + } + ] + }, + { + "wireTag": "created_sub_group_suggestion", + "actionType": "created_subgroup_suggestion", + "fields": [ + { + "name": "id", + "wireName": "jid", + "type": "group_jid", + "required": true + }, + { + "name": "owner", + "wireName": "creator", + "type": "user_jid", + "required": true + }, + { + "name": "subject", + "wireName": "subject", + "type": "string", + "required": true, + "content": true + }, + { + "name": "t", + "wireName": "creation", + "type": "integer", + "required": true + } + ] + }, + { + "wireTag": "revoked_sub_group_suggestions", + "actionType": "revoked_sub_group_suggestions", + "children": [ + { + "name": "subgroupSuggestions", + "wireTag": "sub_group_suggestion", + "fields": [ + { + "name": "id", + "wireName": "jid", + "type": "group_jid", + "required": true + }, + { + "name": "owner", + "wireName": "creator", + "type": "user_jid", + "required": true + } + ] + } + ] + }, + { + "wireTag": "change_number", + "actionType": "subgroup_suggestions_change_number", + "fields": [ + { + "name": "oldOwner", + "wireName": "participant", + "type": "user_jid", + "required": true + }, + { + "name": "newOwner", + "wireName": "jid", + "type": "user_jid", + "required": true + } + ], + "children": [ + { + "name": "subgroupSuggestions", + "wireTag": "sub_group_suggestion", + "fields": [ + { + "name": "jid", + "wireName": "jid", + "type": "group_jid", + "required": true + } + ] + } + ] + }, + { + "wireTag": "member_add_mode", + "actionType": "member_add_mode", + "fields": [ + { + "name": "memberAddMode", + "wireName": "", + "type": "string", + "required": true, + "content": true + } + ] + }, + { + "wireTag": "auto_add_disabled", + "actionType": "general_chat_auto_add_disabled" + }, + { + "wireTag": "group_safety_check", + "actionType": "group_safety_check", + "constantFields": [ + { + "name": "value", + "value": true + } + ] + }, + { + "wireTag": "missing_participant_identification" + } + ] }, { "type": "w:growth", @@ -1767,8 +2887,12 @@ { "method": "attrEnum", "name": "type", - "type": "string", - "required": true + "type": "enum", + "required": true, + "enumKeys": [ + "contacts", + "w:growth" + ] }, { "method": "child", @@ -1821,7 +2945,7 @@ ], "fields": [ { - "method": "attrJidWithType", + "method": "literalJid", "name": "from", "wireName": "from", "type": "jid", @@ -1832,7 +2956,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "waffle" }, { "method": "attrInt", @@ -1852,6 +2977,20 @@ "wireName": "show_user_notif", "type": "enum", "required": false, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInWaffleEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + }, "sourcePath": [ "notification_metadata" ] @@ -1874,6 +3013,20 @@ "wireName": "client_resync", "type": "enum", "required": false, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInWaffleEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + }, "sourcePath": [ "notification_metadata" ] @@ -1894,6 +3047,20 @@ "wireName": "npr", "type": "enum", "required": false, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInWaffleEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + }, "sourcePath": [ "notification_metadata" ] diff --git a/generated/schema/incoming.schema.json b/generated/schema/incoming.schema.json index 5f780a1..9c658b5 100644 --- a/generated/schema/incoming.schema.json +++ b/generated/schema/incoming.schema.json @@ -40,18 +40,118 @@ "description": "The node's text content is pinned to a fixed value (`literalContent(content,\nnode, \"admin_add\")`) — a discriminator for marker union variants. The value is\nin [`ResponseAssertion::value`]; `name` is unused.", "type": "string", "const": "content" + }, + { + "description": "The attribute named by [`ResponseAssertion::name`] must **echo a value taken\nfrom the request** — `literal(attrString, node, \"from\",\nattrStringFromReference(request, [\"to\"]))`. The expected value is not a\nconstant, so [`ResponseAssertion::value`] is absent; where it comes from is in\n[`ResponseAssertion::reference_path`].\n\nThis is the rule 17 of the 26 namespace `IQError…Mixin`s (and every success\nparser) enforce: an answer's `id` must equal the request's `id` and its `from`\nthe request's `to`. An emitter that hardcodes `from=\"s.whatsapp.net\"` produces\nstanzas a real client cannot parse whenever the request went to `g.us`.", + "type": "string", + "const": "reference" } ] }, + "AttrEnumRef": { + "description": "A wire enum a request attribute's value is drawn from, recovered by resolving a\nstructural `o(\"Mod\").EnumName.VARIANT` reference in the builder. String-valued (all\nstanza-attr enums are wire tokens), so a consumer can generate a real enum type.", + "type": "object", + "properties": { + "module": { + "description": "The module that defines it (`WAWebBackendJobs.flow`, `WAWebUsync`, …).", + "type": "string" + }, + "name": { + "description": "The enum's name (`CiphertextType`, `USYNC_ADDRESSING_MODE`, …).", + "type": "string" + }, + "variants": { + "description": "The enum's variants in source order.", + "type": "array", + "items": { + "$ref": "#/$defs/AttrEnumVariant" + } + } + }, + "required": [ + "name", + "module", + "variants" + ] + }, + "AttrEnumVariant": { + "description": "One `NAME: \"wire_value\"` member of an [`AttrEnumRef`].", + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [ + "name", + "value" + ] + }, "ContentType": { "description": "How a child/leaf node's content is accessed in the response parser.", - "type": "string", - "enum": [ - "string", - "bytes", - "nodes" + "oneOf": [ + { + "type": "string", + "enum": [ + "string", + "bytes", + "nodes" + ] + }, + { + "description": "A decimal integer in the element body (`contentUint`, `contentInt`). Distinct\nfrom [`String`] because a consumer that reads it as text has to re-parse, and\nbecause collapsing it onto `String` is how three sibling integer contents ended\nup sharing one generated field.\n\n[`String`]: ContentType::String", + "type": "string", + "const": "integer" + } ] }, + "ErrorArm": { + "description": "One accepted `` shape of a response variant: the `code` and `text` that must\noccur **together**.\n\nA variant accepting `400 bad-request` and `501 feature-not-implemented` cannot be\ndescribed by two independent lists — nothing would then rule out `400\nfeature-not-implemented`, a combination the parser rejects, so an emitter picking one\nvalue from each list produces an unparseable stanza. The pairing is the point.\n\nEvery field is optional because each is a genuine shape: an arm may pin an exact\n`(code, text)`, pin only the code and read the text freely\n(`IQErrorReportTokenValidationFail` accepts any text with 548), or pin neither and\nrange-check the code (the `IQErrorFallback*` arms).", + "type": "object", + "properties": { + "code": { + "description": "The exact `code` this arm pins, when it pins one.", + "type": [ + "integer", + "null" + ], + "format": "int64" + }, + "codeMax": { + "description": "Inclusive upper bound of the same range (see [`code_min`]).\n\n[`code_min`]: ErrorArm::code_min", + "type": [ + "integer", + "null" + ], + "format": "int64" + }, + "codeMin": { + "description": "Inclusive lower bound of the codes this arm accepts, when it range-checks instead\nof pinning.", + "type": [ + "integer", + "null" + ], + "format": "int64" + }, + "name": { + "description": "The disjunction alternative this arm comes from (`IQErrorBadRequest`), when the\nerror is parsed as a `…Errors` union. `None` for an RPC that parses a single\n`` child directly, which has exactly one arm and no name for it.", + "type": [ + "string", + "null" + ] + }, + "text": { + "description": "The exact `text` this arm pins. Absent is a fact, not a gap — see the note above.", + "type": [ + "string", + "null" + ] + } + } + }, "IncomingDef": { "description": "One received stanza's read-shape: which tag it parses, the module that defines the\nparser, and the recovered field tree.", "type": "object", @@ -143,6 +243,17 @@ "type": "string" } }, + "enumRef": { + "description": "The wire enum this field's value is drawn from, when the parser reads it with an\nenum accessor (`attrStringEnum(node, \"state\", o(\"Mod\").ENUM_OFF_ON)`). Resolved\nthe same way the request side resolves [`WapAttrDef::enum_ref`], so a consumer\ncan type the field as that enum instead of a bare string — and an emitter knows\nwhich values are legal instead of guessing from the generated `ENUM_OFF_ON` name.\nAbsent when the enum argument is not a structurally resolvable module export, or\nresolves to a non-string enum (never guessed).\n\n[`WapAttrDef::enum_ref`]: WapAttrDef::enum_ref", + "anyOf": [ + { + "$ref": "#/$defs/AttrEnumRef" + }, + { + "type": "null" + } + ] + }, "intMax": { "description": "Inclusive upper bound from the same `attrIntRange` check (see [`int_min`]).\n\n[`int_min`]: ParsedField::int_min", "type": [ @@ -159,6 +270,13 @@ ], "format": "int64" }, + "literalValue": { + "description": "The fixed value the parser pins this field to — `literal(attrString, participant,\n\"type\", \"admin\")` → `\"admin\"`, `literal(attrInt, error, \"code\", 429)` → `\"429\"`.\nAlways the string form of the literal; [`field_type`] says how to read it (a\n`code` field with `literalValue: \"429\"` is the integer 429 on the wire). On a\n[`ParsedFieldType::Bytes`] field it is **lowercase hex** — the encoding\n[`WapContent::const_bytes`] already uses on the request side —\nand [`byte_length`] is its length: `contentLiteralBytes(node, new Uint8Array([5]))`\n→ `literalValue: \"05\"`, `byteLength: 1`.\n\n[`byte_length`]: ParsedField::byte_length\n\n[`required`] tells the two pinning forms apart, and the difference matters to an\nemitter: a **required** literal (`literal`) is a hard discriminator — the\nattribute MUST be present and equal to this value or the variant does not match;\nan **optional** one (`optionalLiteral`) is pinned only when present — the emitter\nmay omit the attribute, but must never send a contradicting value.\n\n**On a [`ParsedFieldType::Bool`] field the pin is always conditional.** Such a\nfield is a *presence flag* — `{hasListCDhash: m.value != null}` — so its\n`required: true` describes the flag (the parser always produces it), never the\nwire attribute named by [`wire_name`], which by construction may be absent. The\npin constrains that attribute when present, and never the boolean itself.\n\n[`field_type`]: ParsedField::field_type\n[`required`]: ParsedField::required\n[`wire_name`]: ParsedField::wire_name", + "type": [ + "string", + "null" + ] + }, "method": { "type": "string" }, @@ -166,6 +284,16 @@ "description": "The output (struct field) name — the camelCase `makeResult` key in smax.", "type": "string" }, + "referencePath": { + "description": "The field is pinned not to a constant but to **a value taken from the request** —\nthe same echo rule [`AssertionKind::Reference`] carries, in the same\n`attrStringFromReference` path form, but for a pin that is *not* a variant guard.\n\nA required echo (`literal(…, \"from\", ref.to)`) is recorded as an assertion, since\nit must hold for the variant to match at all. An **optional** one\n(`optionalLiteral(…, \"c_dhash\", ref.item.dhash)`) is not a guard — the attribute\nmay be absent — so it lives here instead: an emitter may omit it, but if it sends\nit, the value must be the request's. Mutually exclusive with [`literal_value`],\nand — like it — always conditional when carried on a [`ParsedFieldType::Bool`]\npresence flag.\n\n[`literal_value`]: ParsedField::literal_value", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, "repeats": { "type": [ "boolean", @@ -357,6 +485,16 @@ "null" ] }, + "referencePath": { + "description": "Where the expected value is read from **in the request**, for\n[`AssertionKind::Reference`]. It is the argument list of WA's\n`attrStringFromReference(request, path)` helper: every element but the last is a\nchild tag to descend into, and the last is the attribute name. So `[\"to\"]` means\n\"the request's `to` attribute\" and `[\"account\", \"action\"]` means \"the `action`\nattribute of the request's `` child\".\n\nCarried structurally (rather than left to be inferred from `name`) so a consumer\nnever has to pattern-match attribute names to know an echo rule applies.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, "value": { "type": [ "string", @@ -378,6 +516,24 @@ "$ref": "#/$defs/ResponseAssertion" } }, + "errorArms": { + "description": "The accepted `` shapes, in parser order — **which code goes with which\ntext**. See [`ErrorArm`]; this is the only representation of the vocabulary,\ndeliberately, because the flattened `errorCodes` / `errorTexts` lists it replaced\nlet an emitter combine one arm's code with another's text and produce a stanza no\nbranch accepts.\n\nAn arm describes the *discriminating* `` node. When the variant also pins\nthe node above it, those pins are in [`error_envelope`], and the full shape is\n**arm + envelope**.\n\nTo answer \"does this RPC accept code N / text T?\", scan the arms — the question\nthe flat lists used to answer is one `.iter().any(…)` away, and asking it that way\ncannot produce an invalid pair.\n\n[`error_envelope`]: ResponseVariant::error_envelope", + "type": "array", + "items": { + "$ref": "#/$defs/ErrorArm" + } + }, + "errorEnvelope": { + "description": "Pins on the `` node **enclosing** the one the arms discriminate, for a\ntwo-level error.\n\n`SetResponsePreKeySuccessVnameFailure` is the shape: `` — the\npartial-failure envelope, shared by every arm — wrapping an inner `` whose\ntext the disjunction pins and whose code is range-checked. Pins are partitioned by\nthe node they are read from, so the envelope holds only the enclosing node's and\nthe inner node's shared constraints stay on the arms; mixing them would tell a\nconsumer that code 207 must also fall in 400–599.", + "anyOf": [ + { + "$ref": "#/$defs/ErrorArm" + }, + { + "type": "null" + } + ] + }, "fields": { "type": "array", "items": { @@ -404,15 +560,29 @@ ] }, "ResponseVariantKind": { - "description": "How a response-root union variant classifies (drives codegen `Ok`/`Err` arms).", + "description": "How a response-root union variant classifies (drives codegen `Ok`/`Err` arms).\n\nThe error side is split by **who is at fault**, because that decides what a caller\nshould do: a 4xx will fail again if retried unchanged, a 5xx may not. WA models the\ntwo as separate parsers with disjoint code ranges (`bad-request` 400,\n`rate-overlimit` 429, fallback 400–499 / `internal-server-error` 500, fallback\n500–599), so the split is the protocol's, not an interpretation.\n\nThe side is derived from the **codes** the variant accepts, never from its name: WA\nspells the arms inconsistently (`…ResponseServerError`, but also\n`…ResponseInternalServerError`, and `SetResponsePreKeySuccessVnameFailure` reads as a\nsuccess while asserting `type=\"error\"`). A variant whose codes are mixed or outside\nboth families stays [`Error`] — an error whose side could not be determined, which is\na fact worth stating rather than a coin flip.\n\n[`Error`]: ResponseVariantKind::Error", "oneOf": [ { "type": "string", "enum": [ - "success", - "error" + "success" ] }, + { + "description": "The request was wrong (4xx) — retrying it unchanged will fail again.", + "type": "string", + "const": "client_error" + }, + { + "description": "The server failed (5xx) — the same request may succeed later.", + "type": "string", + "const": "server_error" + }, + { + "description": "An error whose side the accepted codes do not determine.", + "type": "string", + "const": "error" + }, { "description": "A structured non-happy outcome that still parses (Nack, Conflict, …).", "type": "string", diff --git a/generated/schema/iq.schema.json b/generated/schema/iq.schema.json index 4342537..e63ed03 100644 --- a/generated/schema/iq.schema.json +++ b/generated/schema/iq.schema.json @@ -45,6 +45,11 @@ "description": "The node's text content is pinned to a fixed value (`literalContent(content,\nnode, \"admin_add\")`) — a discriminator for marker union variants. The value is\nin [`ResponseAssertion::value`]; `name` is unused.", "type": "string", "const": "content" + }, + { + "description": "The attribute named by [`ResponseAssertion::name`] must **echo a value taken\nfrom the request** — `literal(attrString, node, \"from\",\nattrStringFromReference(request, [\"to\"]))`. The expected value is not a\nconstant, so [`ResponseAssertion::value`] is absent; where it comes from is in\n[`ResponseAssertion::reference_path`].\n\nThis is the rule 17 of the 26 namespace `IQError…Mixin`s (and every success\nparser) enforce: an answer's `id` must equal the request's `id` and its `from`\nthe request's `to`. An emitter that hardcodes `from=\"s.whatsapp.net\"` produces\nstanzas a real client cannot parse whenever the request went to `g.us`.", + "type": "string", + "const": "reference" } ] }, @@ -92,13 +97,66 @@ }, "ContentType": { "description": "How a child/leaf node's content is accessed in the response parser.", - "type": "string", - "enum": [ - "string", - "bytes", - "nodes" + "oneOf": [ + { + "type": "string", + "enum": [ + "string", + "bytes", + "nodes" + ] + }, + { + "description": "A decimal integer in the element body (`contentUint`, `contentInt`). Distinct\nfrom [`String`] because a consumer that reads it as text has to re-parse, and\nbecause collapsing it onto `String` is how three sibling integer contents ended\nup sharing one generated field.\n\n[`String`]: ContentType::String", + "type": "string", + "const": "integer" + } ] }, + "ErrorArm": { + "description": "One accepted `` shape of a response variant: the `code` and `text` that must\noccur **together**.\n\nA variant accepting `400 bad-request` and `501 feature-not-implemented` cannot be\ndescribed by two independent lists — nothing would then rule out `400\nfeature-not-implemented`, a combination the parser rejects, so an emitter picking one\nvalue from each list produces an unparseable stanza. The pairing is the point.\n\nEvery field is optional because each is a genuine shape: an arm may pin an exact\n`(code, text)`, pin only the code and read the text freely\n(`IQErrorReportTokenValidationFail` accepts any text with 548), or pin neither and\nrange-check the code (the `IQErrorFallback*` arms).", + "type": "object", + "properties": { + "code": { + "description": "The exact `code` this arm pins, when it pins one.", + "type": [ + "integer", + "null" + ], + "format": "int64" + }, + "codeMax": { + "description": "Inclusive upper bound of the same range (see [`code_min`]).\n\n[`code_min`]: ErrorArm::code_min", + "type": [ + "integer", + "null" + ], + "format": "int64" + }, + "codeMin": { + "description": "Inclusive lower bound of the codes this arm accepts, when it range-checks instead\nof pinning.", + "type": [ + "integer", + "null" + ], + "format": "int64" + }, + "name": { + "description": "The disjunction alternative this arm comes from (`IQErrorBadRequest`), when the\nerror is parsed as a `…Errors` union. `None` for an RPC that parses a single\n`` child directly, which has exactly one arm and no name for it.", + "type": [ + "string", + "null" + ] + }, + "text": { + "description": "The exact `text` this arm pins. Absent is a fact, not a gap — see the note above.", + "type": [ + "string", + "null" + ] + } + } + }, "IqRequestDef": { "description": "The outgoing request half of an IQ operation.", "type": "object", @@ -250,6 +308,17 @@ "type": "string" } }, + "enumRef": { + "description": "The wire enum this field's value is drawn from, when the parser reads it with an\nenum accessor (`attrStringEnum(node, \"state\", o(\"Mod\").ENUM_OFF_ON)`). Resolved\nthe same way the request side resolves [`WapAttrDef::enum_ref`], so a consumer\ncan type the field as that enum instead of a bare string — and an emitter knows\nwhich values are legal instead of guessing from the generated `ENUM_OFF_ON` name.\nAbsent when the enum argument is not a structurally resolvable module export, or\nresolves to a non-string enum (never guessed).\n\n[`WapAttrDef::enum_ref`]: WapAttrDef::enum_ref", + "anyOf": [ + { + "$ref": "#/$defs/AttrEnumRef" + }, + { + "type": "null" + } + ] + }, "intMax": { "description": "Inclusive upper bound from the same `attrIntRange` check (see [`int_min`]).\n\n[`int_min`]: ParsedField::int_min", "type": [ @@ -266,6 +335,13 @@ ], "format": "int64" }, + "literalValue": { + "description": "The fixed value the parser pins this field to — `literal(attrString, participant,\n\"type\", \"admin\")` → `\"admin\"`, `literal(attrInt, error, \"code\", 429)` → `\"429\"`.\nAlways the string form of the literal; [`field_type`] says how to read it (a\n`code` field with `literalValue: \"429\"` is the integer 429 on the wire). On a\n[`ParsedFieldType::Bytes`] field it is **lowercase hex** — the encoding\n[`WapContent::const_bytes`] already uses on the request side —\nand [`byte_length`] is its length: `contentLiteralBytes(node, new Uint8Array([5]))`\n→ `literalValue: \"05\"`, `byteLength: 1`.\n\n[`byte_length`]: ParsedField::byte_length\n\n[`required`] tells the two pinning forms apart, and the difference matters to an\nemitter: a **required** literal (`literal`) is a hard discriminator — the\nattribute MUST be present and equal to this value or the variant does not match;\nan **optional** one (`optionalLiteral`) is pinned only when present — the emitter\nmay omit the attribute, but must never send a contradicting value.\n\n**On a [`ParsedFieldType::Bool`] field the pin is always conditional.** Such a\nfield is a *presence flag* — `{hasListCDhash: m.value != null}` — so its\n`required: true` describes the flag (the parser always produces it), never the\nwire attribute named by [`wire_name`], which by construction may be absent. The\npin constrains that attribute when present, and never the boolean itself.\n\n[`field_type`]: ParsedField::field_type\n[`required`]: ParsedField::required\n[`wire_name`]: ParsedField::wire_name", + "type": [ + "string", + "null" + ] + }, "method": { "type": "string" }, @@ -273,6 +349,16 @@ "description": "The output (struct field) name — the camelCase `makeResult` key in smax.", "type": "string" }, + "referencePath": { + "description": "The field is pinned not to a constant but to **a value taken from the request** —\nthe same echo rule [`AssertionKind::Reference`] carries, in the same\n`attrStringFromReference` path form, but for a pin that is *not* a variant guard.\n\nA required echo (`literal(…, \"from\", ref.to)`) is recorded as an assertion, since\nit must hold for the variant to match at all. An **optional** one\n(`optionalLiteral(…, \"c_dhash\", ref.item.dhash)`) is not a guard — the attribute\nmay be absent — so it lives here instead: an emitter may omit it, but if it sends\nit, the value must be the request's. Mutually exclusive with [`literal_value`],\nand — like it — always conditional when carried on a [`ParsedFieldType::Bool`]\npresence flag.\n\n[`literal_value`]: ParsedField::literal_value", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, "repeats": { "type": [ "boolean", @@ -464,6 +550,16 @@ "null" ] }, + "referencePath": { + "description": "Where the expected value is read from **in the request**, for\n[`AssertionKind::Reference`]. It is the argument list of WA's\n`attrStringFromReference(request, path)` helper: every element but the last is a\nchild tag to descend into, and the last is the attribute name. So `[\"to\"]` means\n\"the request's `to` attribute\" and `[\"account\", \"action\"]` means \"the `action`\nattribute of the request's `` child\".\n\nCarried structurally (rather than left to be inferred from `name`) so a consumer\nnever has to pattern-match attribute names to know an echo rule applies.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, "value": { "type": [ "string", @@ -485,6 +581,24 @@ "$ref": "#/$defs/ResponseAssertion" } }, + "errorArms": { + "description": "The accepted `` shapes, in parser order — **which code goes with which\ntext**. See [`ErrorArm`]; this is the only representation of the vocabulary,\ndeliberately, because the flattened `errorCodes` / `errorTexts` lists it replaced\nlet an emitter combine one arm's code with another's text and produce a stanza no\nbranch accepts.\n\nAn arm describes the *discriminating* `` node. When the variant also pins\nthe node above it, those pins are in [`error_envelope`], and the full shape is\n**arm + envelope**.\n\nTo answer \"does this RPC accept code N / text T?\", scan the arms — the question\nthe flat lists used to answer is one `.iter().any(…)` away, and asking it that way\ncannot produce an invalid pair.\n\n[`error_envelope`]: ResponseVariant::error_envelope", + "type": "array", + "items": { + "$ref": "#/$defs/ErrorArm" + } + }, + "errorEnvelope": { + "description": "Pins on the `` node **enclosing** the one the arms discriminate, for a\ntwo-level error.\n\n`SetResponsePreKeySuccessVnameFailure` is the shape: `` — the\npartial-failure envelope, shared by every arm — wrapping an inner `` whose\ntext the disjunction pins and whose code is range-checked. Pins are partitioned by\nthe node they are read from, so the envelope holds only the enclosing node's and\nthe inner node's shared constraints stay on the arms; mixing them would tell a\nconsumer that code 207 must also fall in 400–599.", + "anyOf": [ + { + "$ref": "#/$defs/ErrorArm" + }, + { + "type": "null" + } + ] + }, "fields": { "type": "array", "items": { @@ -511,15 +625,29 @@ ] }, "ResponseVariantKind": { - "description": "How a response-root union variant classifies (drives codegen `Ok`/`Err` arms).", + "description": "How a response-root union variant classifies (drives codegen `Ok`/`Err` arms).\n\nThe error side is split by **who is at fault**, because that decides what a caller\nshould do: a 4xx will fail again if retried unchanged, a 5xx may not. WA models the\ntwo as separate parsers with disjoint code ranges (`bad-request` 400,\n`rate-overlimit` 429, fallback 400–499 / `internal-server-error` 500, fallback\n500–599), so the split is the protocol's, not an interpretation.\n\nThe side is derived from the **codes** the variant accepts, never from its name: WA\nspells the arms inconsistently (`…ResponseServerError`, but also\n`…ResponseInternalServerError`, and `SetResponsePreKeySuccessVnameFailure` reads as a\nsuccess while asserting `type=\"error\"`). A variant whose codes are mixed or outside\nboth families stays [`Error`] — an error whose side could not be determined, which is\na fact worth stating rather than a coin flip.\n\n[`Error`]: ResponseVariantKind::Error", "oneOf": [ { "type": "string", "enum": [ - "success", - "error" + "success" ] }, + { + "description": "The request was wrong (4xx) — retrying it unchanged will fail again.", + "type": "string", + "const": "client_error" + }, + { + "description": "The server failed (5xx) — the same request may succeed later.", + "type": "string", + "const": "server_error" + }, + { + "description": "An error whose side the accepted codes do not determine.", + "type": "string", + "const": "error" + }, { "description": "A structured non-happy outcome that still parses (Nack, Conflict, …).", "type": "string", diff --git a/generated/schema/notif.schema.json b/generated/schema/notif.schema.json index db3f109..e13a2d5 100644 --- a/generated/schema/notif.schema.json +++ b/generated/schema/notif.schema.json @@ -56,22 +56,269 @@ "description": "The node's text content is pinned to a fixed value (`literalContent(content,\nnode, \"admin_add\")`) — a discriminator for marker union variants. The value is\nin [`ResponseAssertion::value`]; `name` is unused.", "type": "string", "const": "content" + }, + { + "description": "The attribute named by [`ResponseAssertion::name`] must **echo a value taken\nfrom the request** — `literal(attrString, node, \"from\",\nattrStringFromReference(request, [\"to\"]))`. The expected value is not a\nconstant, so [`ResponseAssertion::value`] is absent; where it comes from is in\n[`ResponseAssertion::reference_path`].\n\nThis is the rule 17 of the 26 namespace `IQError…Mixin`s (and every success\nparser) enforce: an answer's `id` must equal the request's `id` and its `from`\nthe request's `to`. An emitter that hardcodes `from=\"s.whatsapp.net\"` produces\nstanzas a real client cannot parse whenever the request went to `g.us`.", + "type": "string", + "const": "reference" + } + ] + }, + "AttrEnumRef": { + "description": "A wire enum a request attribute's value is drawn from, recovered by resolving a\nstructural `o(\"Mod\").EnumName.VARIANT` reference in the builder. String-valued (all\nstanza-attr enums are wire tokens), so a consumer can generate a real enum type.", + "type": "object", + "properties": { + "module": { + "description": "The module that defines it (`WAWebBackendJobs.flow`, `WAWebUsync`, …).", + "type": "string" + }, + "name": { + "description": "The enum's name (`CiphertextType`, `USYNC_ADDRESSING_MODE`, …).", + "type": "string" + }, + "variants": { + "description": "The enum's variants in source order.", + "type": "array", + "items": { + "$ref": "#/$defs/AttrEnumVariant" + } + } + }, + "required": [ + "name", + "module", + "variants" + ] + }, + "AttrEnumVariant": { + "description": "One `NAME: \"wire_value\"` member of an [`AttrEnumRef`].", + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": "string" } + }, + "required": [ + "name", + "value" ] }, "ContentType": { "description": "How a child/leaf node's content is accessed in the response parser.", - "type": "string", - "enum": [ - "string", - "bytes", - "nodes" + "oneOf": [ + { + "type": "string", + "enum": [ + "string", + "bytes", + "nodes" + ] + }, + { + "description": "A decimal integer in the element body (`contentUint`, `contentInt`). Distinct\nfrom [`String`] because a consumer that reads it as text has to re-parse, and\nbecause collapsing it onto `String` is how three sibling integer contents ended\nup sharing one generated field.\n\n[`String`]: ContentType::String", + "type": "string", + "const": "integer" + } + ] + }, + "ErrorArm": { + "description": "One accepted `` shape of a response variant: the `code` and `text` that must\noccur **together**.\n\nA variant accepting `400 bad-request` and `501 feature-not-implemented` cannot be\ndescribed by two independent lists — nothing would then rule out `400\nfeature-not-implemented`, a combination the parser rejects, so an emitter picking one\nvalue from each list produces an unparseable stanza. The pairing is the point.\n\nEvery field is optional because each is a genuine shape: an arm may pin an exact\n`(code, text)`, pin only the code and read the text freely\n(`IQErrorReportTokenValidationFail` accepts any text with 548), or pin neither and\nrange-check the code (the `IQErrorFallback*` arms).", + "type": "object", + "properties": { + "code": { + "description": "The exact `code` this arm pins, when it pins one.", + "type": [ + "integer", + "null" + ], + "format": "int64" + }, + "codeMax": { + "description": "Inclusive upper bound of the same range (see [`code_min`]).\n\n[`code_min`]: ErrorArm::code_min", + "type": [ + "integer", + "null" + ], + "format": "int64" + }, + "codeMin": { + "description": "Inclusive lower bound of the codes this arm accepts, when it range-checks instead\nof pinning.", + "type": [ + "integer", + "null" + ], + "format": "int64" + }, + "name": { + "description": "The disjunction alternative this arm comes from (`IQErrorBadRequest`), when the\nerror is parsed as a `…Errors` union. `None` for an RPC that parses a single\n`` child directly, which has exactly one arm and no name for it.", + "type": [ + "string", + "null" + ] + }, + "text": { + "description": "The exact `text` this arm pins. Absent is a fact, not a gap — see the note above.", + "type": [ + "string", + "null" + ] + } + } + }, + "NotifActionChild": { + "description": "A repeated sub-element an action arm maps over\n(`mapChildrenWithTag(\"participant\", …)`).", + "type": "object", + "properties": { + "fields": { + "description": "The fields read off each element.", + "type": "array", + "items": { + "$ref": "#/$defs/NotifActionField" + } + }, + "name": { + "description": "The output field the mapped list lands in (`\"participants\"`).", + "type": "string" + }, + "wireTag": { + "description": "The repeated element's wire tag (`\"participant\"`).", + "type": "string" + } + }, + "required": [ + "name", + "wireTag" + ] + }, + "NotifActionConstant": { + "description": "A `key → constant` pair an action arm stamps onto its result unconditionally.", + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "value": { + "$ref": "#/$defs/NotifConstValue" + } + }, + "required": [ + "name", + "value" + ] + }, + "NotifActionDef": { + "description": "One arm of a notification's payload action union: a child tag of the\n`` and the fields the handler reads off it.\n\nWA Web parses these in a `switch (child.tag())` inside the handler (e.g.\n`WAWebHandleGroupNotification`), where each arm returns an object stamped with an\n`actionType`. Two facts there are invisible from the wire alone and cannot be\nderived by a consumer:\n\n1. **The mapping is many-to-one.** Several wire tags normalize onto one\n `actionType` — `ephemeral` and `not_ephemeral` both become `ephemeral`, so a\n consumer that branches on `not_ephemeral` is writing dead code.\n2. **Field names are rebound.** The disappearing-message timer arrives in the\n `expiration` attribute but the action field is called `duration` (the *create*\n payload's spelling, `ephemeralDuration`, belongs to a different shape) — reading\n it under the wrong name silently yields 0.", + "type": "object", + "properties": { + "actionType": { + "description": "The normalized action identity the handler stamps as `actionType`. **Not** always\nequal to [`wire_tag`]: `not_ephemeral` maps to `ephemeral`, `locked`/`unlocked`\nboth map to `restrict`, and so on. `None` when the arm computes it dynamically\n(e.g. `link` picks between three actions by its `link_type` attribute), which is\nrecorded rather than guessed.\n\n[`wire_tag`]: NotifActionDef::wire_tag", + "type": [ + "string", + "null" + ] + }, + "children": { + "description": "Repeated sub-elements the arm maps over (`revoke` → one entry per\n``), each with its own field list.", + "type": "array", + "items": { + "$ref": "#/$defs/NotifActionChild" + } + }, + "constantFields": { + "description": "Output fields the arm sets to a **constant** rather than reading from the wire —\n`not_ephemeral` sets `duration: 0`, `locked` sets `value: true`, `unlocked`\n`value: false`. This is exactly the normalization that is invisible from the\nstanza, and it is what makes the many-to-one tag mapping lossless: `ephemeral`\nvs `not_ephemeral` differ only by this. Sorted by key for determinism.", + "type": "array", + "items": { + "$ref": "#/$defs/NotifActionConstant" + } + }, + "fields": { + "description": "The fields the arm reads off the child node, in source order.", + "type": "array", + "items": { + "$ref": "#/$defs/NotifActionField" + } + }, + "wireTag": { + "description": "The child element's tag on the wire (`\"ephemeral\"`, `\"not_ephemeral\"`,\n`\"subject\"`, …) — the value the handler switches on.", + "type": "string" + } + }, + "required": [ + "wireTag" + ] + }, + "NotifActionField": { + "description": "One field an action arm reads off the wire.", + "type": "object", + "properties": { + "content": { + "description": "The element's text content is read instead of an attribute\n(`child(\"body\").contentString()`).", + "type": "boolean" + }, + "enumRef": { + "description": "The wire enum the value is validated against, when the arm reads it with an enum\naccessor (`child.maybeAttrEnum(\"type\", o(\"WAWebGroupApiConst\").GROUP_PARTICIPANT_TYPES)`).\nWithout it a `\"type\": \"enum\"` field says the value is constrained but not to what,\nwhich leaves a parser and an emitter guessing — the same gap `enumRef` closes on\nthe response side.\n\nAbsent when the accessor validates against an **anonymous** lookup table declared\ninline in the handler (`attrEnumOrNullIfUnknown(\"reason\", v)` where `v` is a local\nobject literal). Such a table has no stable name — the identifier is whatever the\nminifier picked this build — so naming it would churn the IR on every WhatsApp\nrollout and invent an identity the bundle does not have. Reported as unresolved\nrather than faked; recovering those value sets is a separate modelling question.", + "anyOf": [ + { + "$ref": "#/$defs/AttrEnumRef" + }, + { + "type": "null" + } + ] + }, + "name": { + "description": "The output field name in the parsed action (`\"duration\"`).", + "type": "string" + }, + "required": { + "description": "Whether the arm reads the attribute unconditionally (`attrInt(\"expiration\")`) or\nguards on its presence (`hasAttr(\"reason\") ? … : null`, `maybeAttrString`).", + "type": "boolean" + }, + "type": { + "description": "How the value decodes, reusing the response-field type vocabulary.", + "$ref": "#/$defs/ParsedFieldType" + }, + "wireName": { + "description": "The wire attribute it is read from (`\"expiration\"`), or the child tag for a\ncontent read. Differs from [`name`] often enough that assuming they match is the\nbug this field exists to prevent.\n\n[`name`]: NotifActionField::name", + "type": "string" + } + }, + "required": [ + "name", + "wireName", + "type", + "required" + ] + }, + "NotifConstValue": { + "description": "The value of a [`NotifActionConstant`] — the literal kinds a handler arm actually\nstamps (`!0`/`!1`, `0`, a wire string). Deliberately narrower than [`crate::Scalar`]\n(no float) so the notif IR stays `Eq`-comparable for the determinism checks.", + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "integer", + "format": "int64" + }, + { + "type": "string" + } ] }, "NotificationDef": { "description": "One arm of the inner `switch(notification.type)` — a ``\nkind and the handler that parses it.", "type": "object", "properties": { + "actions": { + "description": "The payload **action union** carried inside the notification, when its handler\ndispatches on the child tag (`w:gp2` and friends — see [`NotifActionDef`]).\n[`content`] describes the envelope; this describes what is inside it. Empty for\na notification whose handler carries no such per-child-tag switch.\n\n[`content`]: NotificationDef::content", + "type": "array", + "items": { + "$ref": "#/$defs/NotifActionDef" + } + }, "content": { "description": "The typed content shape parsed from the handler's `WADeprecatedWapParser`\n(Phase 2). `None` when the handler carries no statically-recoverable parser\n(it delegates to a job/sub-module) — the catalog entry still stands.", "anyOf": [ @@ -171,6 +418,17 @@ "type": "string" } }, + "enumRef": { + "description": "The wire enum this field's value is drawn from, when the parser reads it with an\nenum accessor (`attrStringEnum(node, \"state\", o(\"Mod\").ENUM_OFF_ON)`). Resolved\nthe same way the request side resolves [`WapAttrDef::enum_ref`], so a consumer\ncan type the field as that enum instead of a bare string — and an emitter knows\nwhich values are legal instead of guessing from the generated `ENUM_OFF_ON` name.\nAbsent when the enum argument is not a structurally resolvable module export, or\nresolves to a non-string enum (never guessed).\n\n[`WapAttrDef::enum_ref`]: WapAttrDef::enum_ref", + "anyOf": [ + { + "$ref": "#/$defs/AttrEnumRef" + }, + { + "type": "null" + } + ] + }, "intMax": { "description": "Inclusive upper bound from the same `attrIntRange` check (see [`int_min`]).\n\n[`int_min`]: ParsedField::int_min", "type": [ @@ -187,6 +445,13 @@ ], "format": "int64" }, + "literalValue": { + "description": "The fixed value the parser pins this field to — `literal(attrString, participant,\n\"type\", \"admin\")` → `\"admin\"`, `literal(attrInt, error, \"code\", 429)` → `\"429\"`.\nAlways the string form of the literal; [`field_type`] says how to read it (a\n`code` field with `literalValue: \"429\"` is the integer 429 on the wire). On a\n[`ParsedFieldType::Bytes`] field it is **lowercase hex** — the encoding\n[`WapContent::const_bytes`] already uses on the request side —\nand [`byte_length`] is its length: `contentLiteralBytes(node, new Uint8Array([5]))`\n→ `literalValue: \"05\"`, `byteLength: 1`.\n\n[`byte_length`]: ParsedField::byte_length\n\n[`required`] tells the two pinning forms apart, and the difference matters to an\nemitter: a **required** literal (`literal`) is a hard discriminator — the\nattribute MUST be present and equal to this value or the variant does not match;\nan **optional** one (`optionalLiteral`) is pinned only when present — the emitter\nmay omit the attribute, but must never send a contradicting value.\n\n**On a [`ParsedFieldType::Bool`] field the pin is always conditional.** Such a\nfield is a *presence flag* — `{hasListCDhash: m.value != null}` — so its\n`required: true` describes the flag (the parser always produces it), never the\nwire attribute named by [`wire_name`], which by construction may be absent. The\npin constrains that attribute when present, and never the boolean itself.\n\n[`field_type`]: ParsedField::field_type\n[`required`]: ParsedField::required\n[`wire_name`]: ParsedField::wire_name", + "type": [ + "string", + "null" + ] + }, "method": { "type": "string" }, @@ -194,6 +459,16 @@ "description": "The output (struct field) name — the camelCase `makeResult` key in smax.", "type": "string" }, + "referencePath": { + "description": "The field is pinned not to a constant but to **a value taken from the request** —\nthe same echo rule [`AssertionKind::Reference`] carries, in the same\n`attrStringFromReference` path form, but for a pin that is *not* a variant guard.\n\nA required echo (`literal(…, \"from\", ref.to)`) is recorded as an assertion, since\nit must hold for the variant to match at all. An **optional** one\n(`optionalLiteral(…, \"c_dhash\", ref.item.dhash)`) is not a guard — the attribute\nmay be absent — so it lives here instead: an emitter may omit it, but if it sends\nit, the value must be the request's. Mutually exclusive with [`literal_value`],\nand — like it — always conditional when carried on a [`ParsedFieldType::Bool`]\npresence flag.\n\n[`literal_value`]: ParsedField::literal_value", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, "repeats": { "type": [ "boolean", @@ -385,6 +660,16 @@ "null" ] }, + "referencePath": { + "description": "Where the expected value is read from **in the request**, for\n[`AssertionKind::Reference`]. It is the argument list of WA's\n`attrStringFromReference(request, path)` helper: every element but the last is a\nchild tag to descend into, and the last is the attribute name. So `[\"to\"]` means\n\"the request's `to` attribute\" and `[\"account\", \"action\"]` means \"the `action`\nattribute of the request's `` child\".\n\nCarried structurally (rather than left to be inferred from `name`) so a consumer\nnever has to pattern-match attribute names to know an echo rule applies.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, "value": { "type": [ "string", @@ -406,6 +691,24 @@ "$ref": "#/$defs/ResponseAssertion" } }, + "errorArms": { + "description": "The accepted `` shapes, in parser order — **which code goes with which\ntext**. See [`ErrorArm`]; this is the only representation of the vocabulary,\ndeliberately, because the flattened `errorCodes` / `errorTexts` lists it replaced\nlet an emitter combine one arm's code with another's text and produce a stanza no\nbranch accepts.\n\nAn arm describes the *discriminating* `` node. When the variant also pins\nthe node above it, those pins are in [`error_envelope`], and the full shape is\n**arm + envelope**.\n\nTo answer \"does this RPC accept code N / text T?\", scan the arms — the question\nthe flat lists used to answer is one `.iter().any(…)` away, and asking it that way\ncannot produce an invalid pair.\n\n[`error_envelope`]: ResponseVariant::error_envelope", + "type": "array", + "items": { + "$ref": "#/$defs/ErrorArm" + } + }, + "errorEnvelope": { + "description": "Pins on the `` node **enclosing** the one the arms discriminate, for a\ntwo-level error.\n\n`SetResponsePreKeySuccessVnameFailure` is the shape: `` — the\npartial-failure envelope, shared by every arm — wrapping an inner `` whose\ntext the disjunction pins and whose code is range-checked. Pins are partitioned by\nthe node they are read from, so the envelope holds only the enclosing node's and\nthe inner node's shared constraints stay on the arms; mixing them would tell a\nconsumer that code 207 must also fall in 400–599.", + "anyOf": [ + { + "$ref": "#/$defs/ErrorArm" + }, + { + "type": "null" + } + ] + }, "fields": { "type": "array", "items": { @@ -432,15 +735,29 @@ ] }, "ResponseVariantKind": { - "description": "How a response-root union variant classifies (drives codegen `Ok`/`Err` arms).", + "description": "How a response-root union variant classifies (drives codegen `Ok`/`Err` arms).\n\nThe error side is split by **who is at fault**, because that decides what a caller\nshould do: a 4xx will fail again if retried unchanged, a 5xx may not. WA models the\ntwo as separate parsers with disjoint code ranges (`bad-request` 400,\n`rate-overlimit` 429, fallback 400–499 / `internal-server-error` 500, fallback\n500–599), so the split is the protocol's, not an interpretation.\n\nThe side is derived from the **codes** the variant accepts, never from its name: WA\nspells the arms inconsistently (`…ResponseServerError`, but also\n`…ResponseInternalServerError`, and `SetResponsePreKeySuccessVnameFailure` reads as a\nsuccess while asserting `type=\"error\"`). A variant whose codes are mixed or outside\nboth families stays [`Error`] — an error whose side could not be determined, which is\na fact worth stating rather than a coin flip.\n\n[`Error`]: ResponseVariantKind::Error", "oneOf": [ { "type": "string", "enum": [ - "success", - "error" + "success" ] }, + { + "description": "The request was wrong (4xx) — retrying it unchanged will fail again.", + "type": "string", + "const": "client_error" + }, + { + "description": "The server failed (5xx) — the same request may succeed later.", + "type": "string", + "const": "server_error" + }, + { + "description": "An error whose side the accepted codes do not determine.", + "type": "string", + "const": "error" + }, { "description": "A structured non-happy outcome that still parses (Nack, Conflict, …).", "type": "string", diff --git a/generated/schema/srvreq.schema.json b/generated/schema/srvreq.schema.json index 6300ab0..d15b204 100644 --- a/generated/schema/srvreq.schema.json +++ b/generated/schema/srvreq.schema.json @@ -40,18 +40,118 @@ "description": "The node's text content is pinned to a fixed value (`literalContent(content,\nnode, \"admin_add\")`) — a discriminator for marker union variants. The value is\nin [`ResponseAssertion::value`]; `name` is unused.", "type": "string", "const": "content" + }, + { + "description": "The attribute named by [`ResponseAssertion::name`] must **echo a value taken\nfrom the request** — `literal(attrString, node, \"from\",\nattrStringFromReference(request, [\"to\"]))`. The expected value is not a\nconstant, so [`ResponseAssertion::value`] is absent; where it comes from is in\n[`ResponseAssertion::reference_path`].\n\nThis is the rule 17 of the 26 namespace `IQError…Mixin`s (and every success\nparser) enforce: an answer's `id` must equal the request's `id` and its `from`\nthe request's `to`. An emitter that hardcodes `from=\"s.whatsapp.net\"` produces\nstanzas a real client cannot parse whenever the request went to `g.us`.", + "type": "string", + "const": "reference" } ] }, + "AttrEnumRef": { + "description": "A wire enum a request attribute's value is drawn from, recovered by resolving a\nstructural `o(\"Mod\").EnumName.VARIANT` reference in the builder. String-valued (all\nstanza-attr enums are wire tokens), so a consumer can generate a real enum type.", + "type": "object", + "properties": { + "module": { + "description": "The module that defines it (`WAWebBackendJobs.flow`, `WAWebUsync`, …).", + "type": "string" + }, + "name": { + "description": "The enum's name (`CiphertextType`, `USYNC_ADDRESSING_MODE`, …).", + "type": "string" + }, + "variants": { + "description": "The enum's variants in source order.", + "type": "array", + "items": { + "$ref": "#/$defs/AttrEnumVariant" + } + } + }, + "required": [ + "name", + "module", + "variants" + ] + }, + "AttrEnumVariant": { + "description": "One `NAME: \"wire_value\"` member of an [`AttrEnumRef`].", + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [ + "name", + "value" + ] + }, "ContentType": { "description": "How a child/leaf node's content is accessed in the response parser.", - "type": "string", - "enum": [ - "string", - "bytes", - "nodes" + "oneOf": [ + { + "type": "string", + "enum": [ + "string", + "bytes", + "nodes" + ] + }, + { + "description": "A decimal integer in the element body (`contentUint`, `contentInt`). Distinct\nfrom [`String`] because a consumer that reads it as text has to re-parse, and\nbecause collapsing it onto `String` is how three sibling integer contents ended\nup sharing one generated field.\n\n[`String`]: ContentType::String", + "type": "string", + "const": "integer" + } ] }, + "ErrorArm": { + "description": "One accepted `` shape of a response variant: the `code` and `text` that must\noccur **together**.\n\nA variant accepting `400 bad-request` and `501 feature-not-implemented` cannot be\ndescribed by two independent lists — nothing would then rule out `400\nfeature-not-implemented`, a combination the parser rejects, so an emitter picking one\nvalue from each list produces an unparseable stanza. The pairing is the point.\n\nEvery field is optional because each is a genuine shape: an arm may pin an exact\n`(code, text)`, pin only the code and read the text freely\n(`IQErrorReportTokenValidationFail` accepts any text with 548), or pin neither and\nrange-check the code (the `IQErrorFallback*` arms).", + "type": "object", + "properties": { + "code": { + "description": "The exact `code` this arm pins, when it pins one.", + "type": [ + "integer", + "null" + ], + "format": "int64" + }, + "codeMax": { + "description": "Inclusive upper bound of the same range (see [`code_min`]).\n\n[`code_min`]: ErrorArm::code_min", + "type": [ + "integer", + "null" + ], + "format": "int64" + }, + "codeMin": { + "description": "Inclusive lower bound of the codes this arm accepts, when it range-checks instead\nof pinning.", + "type": [ + "integer", + "null" + ], + "format": "int64" + }, + "name": { + "description": "The disjunction alternative this arm comes from (`IQErrorBadRequest`), when the\nerror is parsed as a `…Errors` union. `None` for an RPC that parses a single\n`` child directly, which has exactly one arm and no name for it.", + "type": [ + "string", + "null" + ] + }, + "text": { + "description": "The exact `text` this arm pins. Absent is a fact, not a gap — see the note above.", + "type": [ + "string", + "null" + ] + } + } + }, "ParsedField": { "description": "One field extracted from a response stanza by a parser.\n\n`method` is the parser accessor used (e.g. `attrString`, `maybeChild`,\n`forEachChildWithTag`) and is left open-ended (free-form string) to track the\nreal WA accessor surface; the codegen switches on it.", "type": "object", @@ -110,6 +210,17 @@ "type": "string" } }, + "enumRef": { + "description": "The wire enum this field's value is drawn from, when the parser reads it with an\nenum accessor (`attrStringEnum(node, \"state\", o(\"Mod\").ENUM_OFF_ON)`). Resolved\nthe same way the request side resolves [`WapAttrDef::enum_ref`], so a consumer\ncan type the field as that enum instead of a bare string — and an emitter knows\nwhich values are legal instead of guessing from the generated `ENUM_OFF_ON` name.\nAbsent when the enum argument is not a structurally resolvable module export, or\nresolves to a non-string enum (never guessed).\n\n[`WapAttrDef::enum_ref`]: WapAttrDef::enum_ref", + "anyOf": [ + { + "$ref": "#/$defs/AttrEnumRef" + }, + { + "type": "null" + } + ] + }, "intMax": { "description": "Inclusive upper bound from the same `attrIntRange` check (see [`int_min`]).\n\n[`int_min`]: ParsedField::int_min", "type": [ @@ -126,6 +237,13 @@ ], "format": "int64" }, + "literalValue": { + "description": "The fixed value the parser pins this field to — `literal(attrString, participant,\n\"type\", \"admin\")` → `\"admin\"`, `literal(attrInt, error, \"code\", 429)` → `\"429\"`.\nAlways the string form of the literal; [`field_type`] says how to read it (a\n`code` field with `literalValue: \"429\"` is the integer 429 on the wire). On a\n[`ParsedFieldType::Bytes`] field it is **lowercase hex** — the encoding\n[`WapContent::const_bytes`] already uses on the request side —\nand [`byte_length`] is its length: `contentLiteralBytes(node, new Uint8Array([5]))`\n→ `literalValue: \"05\"`, `byteLength: 1`.\n\n[`byte_length`]: ParsedField::byte_length\n\n[`required`] tells the two pinning forms apart, and the difference matters to an\nemitter: a **required** literal (`literal`) is a hard discriminator — the\nattribute MUST be present and equal to this value or the variant does not match;\nan **optional** one (`optionalLiteral`) is pinned only when present — the emitter\nmay omit the attribute, but must never send a contradicting value.\n\n**On a [`ParsedFieldType::Bool`] field the pin is always conditional.** Such a\nfield is a *presence flag* — `{hasListCDhash: m.value != null}` — so its\n`required: true` describes the flag (the parser always produces it), never the\nwire attribute named by [`wire_name`], which by construction may be absent. The\npin constrains that attribute when present, and never the boolean itself.\n\n[`field_type`]: ParsedField::field_type\n[`required`]: ParsedField::required\n[`wire_name`]: ParsedField::wire_name", + "type": [ + "string", + "null" + ] + }, "method": { "type": "string" }, @@ -133,6 +251,16 @@ "description": "The output (struct field) name — the camelCase `makeResult` key in smax.", "type": "string" }, + "referencePath": { + "description": "The field is pinned not to a constant but to **a value taken from the request** —\nthe same echo rule [`AssertionKind::Reference`] carries, in the same\n`attrStringFromReference` path form, but for a pin that is *not* a variant guard.\n\nA required echo (`literal(…, \"from\", ref.to)`) is recorded as an assertion, since\nit must hold for the variant to match at all. An **optional** one\n(`optionalLiteral(…, \"c_dhash\", ref.item.dhash)`) is not a guard — the attribute\nmay be absent — so it lives here instead: an emitter may omit it, but if it sends\nit, the value must be the request's. Mutually exclusive with [`literal_value`],\nand — like it — always conditional when carried on a [`ParsedFieldType::Bool`]\npresence flag.\n\n[`literal_value`]: ParsedField::literal_value", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, "repeats": { "type": [ "boolean", @@ -324,6 +452,16 @@ "null" ] }, + "referencePath": { + "description": "Where the expected value is read from **in the request**, for\n[`AssertionKind::Reference`]. It is the argument list of WA's\n`attrStringFromReference(request, path)` helper: every element but the last is a\nchild tag to descend into, and the last is the attribute name. So `[\"to\"]` means\n\"the request's `to` attribute\" and `[\"account\", \"action\"]` means \"the `action`\nattribute of the request's `` child\".\n\nCarried structurally (rather than left to be inferred from `name`) so a consumer\nnever has to pattern-match attribute names to know an echo rule applies.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, "value": { "type": [ "string", @@ -345,6 +483,24 @@ "$ref": "#/$defs/ResponseAssertion" } }, + "errorArms": { + "description": "The accepted `` shapes, in parser order — **which code goes with which\ntext**. See [`ErrorArm`]; this is the only representation of the vocabulary,\ndeliberately, because the flattened `errorCodes` / `errorTexts` lists it replaced\nlet an emitter combine one arm's code with another's text and produce a stanza no\nbranch accepts.\n\nAn arm describes the *discriminating* `` node. When the variant also pins\nthe node above it, those pins are in [`error_envelope`], and the full shape is\n**arm + envelope**.\n\nTo answer \"does this RPC accept code N / text T?\", scan the arms — the question\nthe flat lists used to answer is one `.iter().any(…)` away, and asking it that way\ncannot produce an invalid pair.\n\n[`error_envelope`]: ResponseVariant::error_envelope", + "type": "array", + "items": { + "$ref": "#/$defs/ErrorArm" + } + }, + "errorEnvelope": { + "description": "Pins on the `` node **enclosing** the one the arms discriminate, for a\ntwo-level error.\n\n`SetResponsePreKeySuccessVnameFailure` is the shape: `` — the\npartial-failure envelope, shared by every arm — wrapping an inner `` whose\ntext the disjunction pins and whose code is range-checked. Pins are partitioned by\nthe node they are read from, so the envelope holds only the enclosing node's and\nthe inner node's shared constraints stay on the arms; mixing them would tell a\nconsumer that code 207 must also fall in 400–599.", + "anyOf": [ + { + "$ref": "#/$defs/ErrorArm" + }, + { + "type": "null" + } + ] + }, "fields": { "type": "array", "items": { @@ -371,15 +527,29 @@ ] }, "ResponseVariantKind": { - "description": "How a response-root union variant classifies (drives codegen `Ok`/`Err` arms).", + "description": "How a response-root union variant classifies (drives codegen `Ok`/`Err` arms).\n\nThe error side is split by **who is at fault**, because that decides what a caller\nshould do: a 4xx will fail again if retried unchanged, a 5xx may not. WA models the\ntwo as separate parsers with disjoint code ranges (`bad-request` 400,\n`rate-overlimit` 429, fallback 400–499 / `internal-server-error` 500, fallback\n500–599), so the split is the protocol's, not an interpretation.\n\nThe side is derived from the **codes** the variant accepts, never from its name: WA\nspells the arms inconsistently (`…ResponseServerError`, but also\n`…ResponseInternalServerError`, and `SetResponsePreKeySuccessVnameFailure` reads as a\nsuccess while asserting `type=\"error\"`). A variant whose codes are mixed or outside\nboth families stays [`Error`] — an error whose side could not be determined, which is\na fact worth stating rather than a coin flip.\n\n[`Error`]: ResponseVariantKind::Error", "oneOf": [ { "type": "string", "enum": [ - "success", - "error" + "success" ] }, + { + "description": "The request was wrong (4xx) — retrying it unchanged will fail again.", + "type": "string", + "const": "client_error" + }, + { + "description": "The server failed (5xx) — the same request may succeed later.", + "type": "string", + "const": "server_error" + }, + { + "description": "An error whose side the accepted codes do not determine.", + "type": "string", + "const": "error" + }, { "description": "A structured non-happy outcome that still parses (Nack, Conflict, …).", "type": "string", diff --git a/generated/schema/stanza.schema.json b/generated/schema/stanza.schema.json index 31e3ed5..c0d0fc9 100644 --- a/generated/schema/stanza.schema.json +++ b/generated/schema/stanza.schema.json @@ -39,6 +39,11 @@ "description": "The node's text content is pinned to a fixed value (`literalContent(content,\nnode, \"admin_add\")`) — a discriminator for marker union variants. The value is\nin [`ResponseAssertion::value`]; `name` is unused.", "type": "string", "const": "content" + }, + { + "description": "The attribute named by [`ResponseAssertion::name`] must **echo a value taken\nfrom the request** — `literal(attrString, node, \"from\",\nattrStringFromReference(request, [\"to\"]))`. The expected value is not a\nconstant, so [`ResponseAssertion::value`] is absent; where it comes from is in\n[`ResponseAssertion::reference_path`].\n\nThis is the rule 17 of the 26 namespace `IQError…Mixin`s (and every success\nparser) enforce: an answer's `id` must equal the request's `id` and its `from`\nthe request's `to`. An emitter that hardcodes `from=\"s.whatsapp.net\"` produces\nstanzas a real client cannot parse whenever the request went to `g.us`.", + "type": "string", + "const": "reference" } ] }, @@ -86,11 +91,20 @@ }, "ContentType": { "description": "How a child/leaf node's content is accessed in the response parser.", - "type": "string", - "enum": [ - "string", - "bytes", - "nodes" + "oneOf": [ + { + "type": "string", + "enum": [ + "string", + "bytes", + "nodes" + ] + }, + { + "description": "A decimal integer in the element body (`contentUint`, `contentInt`). Distinct\nfrom [`String`] because a consumer that reads it as text has to re-parse, and\nbecause collapsing it onto `String` is how three sibling integer contents ended\nup sharing one generated field.\n\n[`String`]: ContentType::String", + "type": "string", + "const": "integer" + } ] }, "Direction": { @@ -101,6 +115,50 @@ "incoming" ] }, + "ErrorArm": { + "description": "One accepted `` shape of a response variant: the `code` and `text` that must\noccur **together**.\n\nA variant accepting `400 bad-request` and `501 feature-not-implemented` cannot be\ndescribed by two independent lists — nothing would then rule out `400\nfeature-not-implemented`, a combination the parser rejects, so an emitter picking one\nvalue from each list produces an unparseable stanza. The pairing is the point.\n\nEvery field is optional because each is a genuine shape: an arm may pin an exact\n`(code, text)`, pin only the code and read the text freely\n(`IQErrorReportTokenValidationFail` accepts any text with 548), or pin neither and\nrange-check the code (the `IQErrorFallback*` arms).", + "type": "object", + "properties": { + "code": { + "description": "The exact `code` this arm pins, when it pins one.", + "type": [ + "integer", + "null" + ], + "format": "int64" + }, + "codeMax": { + "description": "Inclusive upper bound of the same range (see [`code_min`]).\n\n[`code_min`]: ErrorArm::code_min", + "type": [ + "integer", + "null" + ], + "format": "int64" + }, + "codeMin": { + "description": "Inclusive lower bound of the codes this arm accepts, when it range-checks instead\nof pinning.", + "type": [ + "integer", + "null" + ], + "format": "int64" + }, + "name": { + "description": "The disjunction alternative this arm comes from (`IQErrorBadRequest`), when the\nerror is parsed as a `…Errors` union. `None` for an RPC that parses a single\n`` child directly, which has exactly one arm and no name for it.", + "type": [ + "string", + "null" + ] + }, + "text": { + "description": "The exact `text` this arm pins. Absent is a fact, not a gap — see the note above.", + "type": [ + "string", + "null" + ] + } + } + }, "ParsedField": { "description": "One field extracted from a response stanza by a parser.\n\n`method` is the parser accessor used (e.g. `attrString`, `maybeChild`,\n`forEachChildWithTag`) and is left open-ended (free-form string) to track the\nreal WA accessor surface; the codegen switches on it.", "type": "object", @@ -159,6 +217,17 @@ "type": "string" } }, + "enumRef": { + "description": "The wire enum this field's value is drawn from, when the parser reads it with an\nenum accessor (`attrStringEnum(node, \"state\", o(\"Mod\").ENUM_OFF_ON)`). Resolved\nthe same way the request side resolves [`WapAttrDef::enum_ref`], so a consumer\ncan type the field as that enum instead of a bare string — and an emitter knows\nwhich values are legal instead of guessing from the generated `ENUM_OFF_ON` name.\nAbsent when the enum argument is not a structurally resolvable module export, or\nresolves to a non-string enum (never guessed).\n\n[`WapAttrDef::enum_ref`]: WapAttrDef::enum_ref", + "anyOf": [ + { + "$ref": "#/$defs/AttrEnumRef" + }, + { + "type": "null" + } + ] + }, "intMax": { "description": "Inclusive upper bound from the same `attrIntRange` check (see [`int_min`]).\n\n[`int_min`]: ParsedField::int_min", "type": [ @@ -175,6 +244,13 @@ ], "format": "int64" }, + "literalValue": { + "description": "The fixed value the parser pins this field to — `literal(attrString, participant,\n\"type\", \"admin\")` → `\"admin\"`, `literal(attrInt, error, \"code\", 429)` → `\"429\"`.\nAlways the string form of the literal; [`field_type`] says how to read it (a\n`code` field with `literalValue: \"429\"` is the integer 429 on the wire). On a\n[`ParsedFieldType::Bytes`] field it is **lowercase hex** — the encoding\n[`WapContent::const_bytes`] already uses on the request side —\nand [`byte_length`] is its length: `contentLiteralBytes(node, new Uint8Array([5]))`\n→ `literalValue: \"05\"`, `byteLength: 1`.\n\n[`byte_length`]: ParsedField::byte_length\n\n[`required`] tells the two pinning forms apart, and the difference matters to an\nemitter: a **required** literal (`literal`) is a hard discriminator — the\nattribute MUST be present and equal to this value or the variant does not match;\nan **optional** one (`optionalLiteral`) is pinned only when present — the emitter\nmay omit the attribute, but must never send a contradicting value.\n\n**On a [`ParsedFieldType::Bool`] field the pin is always conditional.** Such a\nfield is a *presence flag* — `{hasListCDhash: m.value != null}` — so its\n`required: true` describes the flag (the parser always produces it), never the\nwire attribute named by [`wire_name`], which by construction may be absent. The\npin constrains that attribute when present, and never the boolean itself.\n\n[`field_type`]: ParsedField::field_type\n[`required`]: ParsedField::required\n[`wire_name`]: ParsedField::wire_name", + "type": [ + "string", + "null" + ] + }, "method": { "type": "string" }, @@ -182,6 +258,16 @@ "description": "The output (struct field) name — the camelCase `makeResult` key in smax.", "type": "string" }, + "referencePath": { + "description": "The field is pinned not to a constant but to **a value taken from the request** —\nthe same echo rule [`AssertionKind::Reference`] carries, in the same\n`attrStringFromReference` path form, but for a pin that is *not* a variant guard.\n\nA required echo (`literal(…, \"from\", ref.to)`) is recorded as an assertion, since\nit must hold for the variant to match at all. An **optional** one\n(`optionalLiteral(…, \"c_dhash\", ref.item.dhash)`) is not a guard — the attribute\nmay be absent — so it lives here instead: an emitter may omit it, but if it sends\nit, the value must be the request's. Mutually exclusive with [`literal_value`],\nand — like it — always conditional when carried on a [`ParsedFieldType::Bool`]\npresence flag.\n\n[`literal_value`]: ParsedField::literal_value", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, "repeats": { "type": [ "boolean", @@ -373,6 +459,16 @@ "null" ] }, + "referencePath": { + "description": "Where the expected value is read from **in the request**, for\n[`AssertionKind::Reference`]. It is the argument list of WA's\n`attrStringFromReference(request, path)` helper: every element but the last is a\nchild tag to descend into, and the last is the attribute name. So `[\"to\"]` means\n\"the request's `to` attribute\" and `[\"account\", \"action\"]` means \"the `action`\nattribute of the request's `` child\".\n\nCarried structurally (rather than left to be inferred from `name`) so a consumer\nnever has to pattern-match attribute names to know an echo rule applies.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, "value": { "type": [ "string", @@ -394,6 +490,24 @@ "$ref": "#/$defs/ResponseAssertion" } }, + "errorArms": { + "description": "The accepted `` shapes, in parser order — **which code goes with which\ntext**. See [`ErrorArm`]; this is the only representation of the vocabulary,\ndeliberately, because the flattened `errorCodes` / `errorTexts` lists it replaced\nlet an emitter combine one arm's code with another's text and produce a stanza no\nbranch accepts.\n\nAn arm describes the *discriminating* `` node. When the variant also pins\nthe node above it, those pins are in [`error_envelope`], and the full shape is\n**arm + envelope**.\n\nTo answer \"does this RPC accept code N / text T?\", scan the arms — the question\nthe flat lists used to answer is one `.iter().any(…)` away, and asking it that way\ncannot produce an invalid pair.\n\n[`error_envelope`]: ResponseVariant::error_envelope", + "type": "array", + "items": { + "$ref": "#/$defs/ErrorArm" + } + }, + "errorEnvelope": { + "description": "Pins on the `` node **enclosing** the one the arms discriminate, for a\ntwo-level error.\n\n`SetResponsePreKeySuccessVnameFailure` is the shape: `` — the\npartial-failure envelope, shared by every arm — wrapping an inner `` whose\ntext the disjunction pins and whose code is range-checked. Pins are partitioned by\nthe node they are read from, so the envelope holds only the enclosing node's and\nthe inner node's shared constraints stay on the arms; mixing them would tell a\nconsumer that code 207 must also fall in 400–599.", + "anyOf": [ + { + "$ref": "#/$defs/ErrorArm" + }, + { + "type": "null" + } + ] + }, "fields": { "type": "array", "items": { @@ -420,15 +534,29 @@ ] }, "ResponseVariantKind": { - "description": "How a response-root union variant classifies (drives codegen `Ok`/`Err` arms).", + "description": "How a response-root union variant classifies (drives codegen `Ok`/`Err` arms).\n\nThe error side is split by **who is at fault**, because that decides what a caller\nshould do: a 4xx will fail again if retried unchanged, a 5xx may not. WA models the\ntwo as separate parsers with disjoint code ranges (`bad-request` 400,\n`rate-overlimit` 429, fallback 400–499 / `internal-server-error` 500, fallback\n500–599), so the split is the protocol's, not an interpretation.\n\nThe side is derived from the **codes** the variant accepts, never from its name: WA\nspells the arms inconsistently (`…ResponseServerError`, but also\n`…ResponseInternalServerError`, and `SetResponsePreKeySuccessVnameFailure` reads as a\nsuccess while asserting `type=\"error\"`). A variant whose codes are mixed or outside\nboth families stays [`Error`] — an error whose side could not be determined, which is\na fact worth stating rather than a coin flip.\n\n[`Error`]: ResponseVariantKind::Error", "oneOf": [ { "type": "string", "enum": [ - "success", - "error" + "success" ] }, + { + "description": "The request was wrong (4xx) — retrying it unchanged will fail again.", + "type": "string", + "const": "client_error" + }, + { + "description": "The server failed (5xx) — the same request may succeed later.", + "type": "string", + "const": "server_error" + }, + { + "description": "An error whose side the accepted codes do not determine.", + "type": "string", + "const": "error" + }, { "description": "A structured non-happy outcome that still parses (Nack, Conflict, …).", "type": "string", diff --git a/generated/srvreq/index.json b/generated/srvreq/index.json index 1cfc2a3..f3694cc 100644 --- a/generated/srvreq/index.json +++ b/generated/srvreq/index.json @@ -1,5 +1,5 @@ { - "schemaVersion": "1.0.0", + "schemaVersion": "2.0.0", "waVersion": "2.3000.1043899084", "requests": [ { @@ -20,7 +20,7 @@ ], "fields": [ { - "method": "attrJidWithType", + "method": "literalJid", "name": "from", "wireName": "from", "type": "jid", @@ -38,7 +38,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "business" }, { "method": "attrString", @@ -96,6 +97,20 @@ "wireName": "display", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_INFO_WARNING", + "module": "WASmaxInBizCtwaActionEnums", + "variants": [ + { + "name": "info", + "value": "info" + }, + { + "name": "warning", + "value": "warning" + } + ] + }, "sourcePath": [ "config" ] @@ -106,6 +121,20 @@ "wireName": "revoked", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInBizCtwaActionEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + }, "sourcePath": [ "config" ] @@ -450,7 +479,7 @@ ], "fields": [ { - "method": "attrJidWithType", + "method": "literalJid", "name": "from", "wireName": "from", "type": "jid", @@ -468,7 +497,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "business" }, { "method": "contentString", @@ -523,7 +553,7 @@ ], "fields": [ { - "method": "attrJidWithType", + "method": "literalJid", "name": "from", "wireName": "from", "type": "jid", @@ -541,7 +571,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "business" }, { "method": "child", @@ -556,6 +587,24 @@ "wireName": "value", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_FALSE_NOTSET_TRUE", + "module": "WASmaxInBizSettingsEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "notset", + "value": "notset" + }, + { + "name": "true", + "value": "true" + } + ] + }, "sourcePath": [ "smb_data_sharing_with_meta_consent" ] @@ -617,7 +666,7 @@ ], "fields": [ { - "method": "attrJidWithType", + "method": "literalJid", "name": "from", "wireName": "from", "type": "jid", @@ -628,7 +677,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "hosted" }, { "method": "attrEnum", @@ -636,6 +686,24 @@ "wireName": "product_surface", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_AIFROMMETA_AUTOMATION_BUSINESSPLATFORM", + "module": "WASmaxInCoexistenceEnums", + "variants": [ + { + "name": "ai_from_meta", + "value": "ai_from_meta" + }, + { + "name": "automation", + "value": "automation" + }, + { + "name": "business_platform", + "value": "business_platform" + } + ] + }, "sourcePath": [ "offboarding" ] @@ -751,7 +819,7 @@ ], "fields": [ { - "method": "attrJidWithType", + "method": "literalJid", "name": "from", "wireName": "from", "type": "jid", @@ -762,7 +830,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "hosted" }, { "method": "attrEnum", @@ -770,6 +839,20 @@ "wireName": "status", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_COMPLETED_FAILED", + "module": "WASmaxInCoexistenceEnums", + "variants": [ + { + "name": "completed", + "value": "completed" + }, + { + "name": "failed", + "value": "failed" + } + ] + }, "sourcePath": [ "onboarding_status" ] @@ -786,7 +869,25 @@ "name": "productSurface", "wireName": "product_surface", "type": "enum", - "required": true + "required": true, + "enumRef": { + "name": "ENUM_AIFROMMETA_AUTOMATION_BUSINESSPLATFORM", + "module": "WASmaxInCoexistenceEnums", + "variants": [ + { + "name": "ai_from_meta", + "value": "ai_from_meta" + }, + { + "name": "automation", + "value": "automation" + }, + { + "name": "business_platform", + "value": "business_platform" + } + ] + } } ], "repeats": false @@ -906,10 +1007,11 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "w:gp2" }, { - "method": "attrJidWithType", + "method": "literalJid", "name": "from", "wireName": "from", "type": "jid", @@ -983,10 +1085,11 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "passkey_prologue_request" }, { - "method": "attrJidWithType", + "method": "literalJid", "name": "from", "wireName": "from", "type": "jid", @@ -1058,10 +1161,11 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "link_code_companion_reg" }, { - "method": "attrJidWithType", + "method": "literalJid", "name": "from", "wireName": "from", "type": "jid", @@ -1073,6 +1177,7 @@ "wireName": "stage", "type": "string", "required": true, + "literalValue": "primary_hello", "sourcePath": [ "link_code_companion_reg" ] @@ -1155,10 +1260,11 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "link_code_companion_reg" }, { - "method": "attrJidWithType", + "method": "literalJid", "name": "from", "wireName": "from", "type": "jid", @@ -1170,6 +1276,7 @@ "wireName": "stage", "type": "string", "required": true, + "literalValue": "refresh_code", "sourcePath": [ "link_code_companion_reg" ] @@ -1180,6 +1287,20 @@ "wireName": "force_manual_refresh", "type": "enum", "required": false, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInMdEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + }, "sourcePath": [ "link_code_companion_reg" ] @@ -1242,10 +1363,11 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "crsc_continuation" }, { - "method": "attrJidWithType", + "method": "literalJid", "name": "from", "wireName": "from", "type": "jid", @@ -1359,7 +1481,8 @@ "name": "isSender", "wireName": "is_sender", "type": "string", - "required": false + "required": false, + "literalValue": "true" }, { "method": "", @@ -1494,6 +1617,7 @@ "wireName": "questiontype", "type": "string", "required": true, + "literalValue": "question", "sourcePath": [ "meta" ] @@ -1510,6 +1634,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -1549,7 +1674,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" }, { "method": "", @@ -1563,6 +1689,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -1592,6 +1719,92 @@ "wireName": "mediatype", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_1PSTICKER_AUDIO_AVATARSTICKER_CATALOGLINK_COLLECTION_DOCUMENT_GENAISTICKER_GIF_IMAGE_MOTIONPHOTO_MOTIONVIDEO_PRODUCTLINK_PTT_PTV_STICKER_STICKERPACK_URL_USERCREATEDSTICKER_VCARD_VIDEO", + "module": "WASmaxInNewslettersEnums", + "variants": [ + { + "name": "1p_sticker", + "value": "1p_sticker" + }, + { + "name": "audio", + "value": "audio" + }, + { + "name": "avatar_sticker", + "value": "avatar_sticker" + }, + { + "name": "cataloglink", + "value": "cataloglink" + }, + { + "name": "collection", + "value": "collection" + }, + { + "name": "document", + "value": "document" + }, + { + "name": "genai_sticker", + "value": "genai_sticker" + }, + { + "name": "gif", + "value": "gif" + }, + { + "name": "image", + "value": "image" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "motion_video", + "value": "motion_video" + }, + { + "name": "productlink", + "value": "productlink" + }, + { + "name": "ptt", + "value": "ptt" + }, + { + "name": "ptv", + "value": "ptv" + }, + { + "name": "sticker", + "value": "sticker" + }, + { + "name": "sticker_pack", + "value": "sticker_pack" + }, + { + "name": "url", + "value": "url" + }, + { + "name": "user_created_sticker", + "value": "user_created_sticker" + }, + { + "name": "vcard", + "value": "vcard" + }, + { + "name": "video", + "value": "video" + } + ] + }, "sourcePath": [ "plaintext" ] @@ -1619,7 +1832,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" }, { "method": "", @@ -1633,6 +1847,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -1652,6 +1867,40 @@ "wireName": "message_association_type", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_HDIMAGEDUALUPLOAD_HDVIDEODUALUPLOAD_HEVCVIDEODUALUPLOAD_MEDIAPOLL_MOTIONPHOTO_POLLADDOPTION_STICKERANNOTATION", + "module": "WASmaxInNewslettersEnums", + "variants": [ + { + "name": "hd_image_dual_upload", + "value": "hd_image_dual_upload" + }, + { + "name": "hd_video_dual_upload", + "value": "hd_video_dual_upload" + }, + { + "name": "hevc_video_dual_upload", + "value": "hevc_video_dual_upload" + }, + { + "name": "media_poll", + "value": "media_poll" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "poll_add_option", + "value": "poll_add_option" + }, + { + "name": "sticker_annotation", + "value": "sticker_annotation" + } + ] + }, "sourcePath": [ "meta" ] @@ -1709,7 +1958,8 @@ "name": "edit", "wireName": "edit", "type": "string", - "required": true + "required": true, + "literalValue": "3" }, { "method": "", @@ -1723,6 +1973,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -1745,6 +1996,7 @@ "wireName": "questiontype", "type": "string", "required": true, + "literalValue": "reply", "sourcePath": [ "meta" ] @@ -1761,6 +2013,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -1800,7 +2053,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" }, { "method": "", @@ -1814,6 +2068,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -1843,6 +2098,92 @@ "wireName": "mediatype", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_1PSTICKER_AUDIO_AVATARSTICKER_CATALOGLINK_COLLECTION_DOCUMENT_GENAISTICKER_GIF_IMAGE_MOTIONPHOTO_MOTIONVIDEO_PRODUCTLINK_PTT_PTV_STICKER_STICKERPACK_URL_USERCREATEDSTICKER_VCARD_VIDEO", + "module": "WASmaxInNewslettersEnums", + "variants": [ + { + "name": "1p_sticker", + "value": "1p_sticker" + }, + { + "name": "audio", + "value": "audio" + }, + { + "name": "avatar_sticker", + "value": "avatar_sticker" + }, + { + "name": "cataloglink", + "value": "cataloglink" + }, + { + "name": "collection", + "value": "collection" + }, + { + "name": "document", + "value": "document" + }, + { + "name": "genai_sticker", + "value": "genai_sticker" + }, + { + "name": "gif", + "value": "gif" + }, + { + "name": "image", + "value": "image" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "motion_video", + "value": "motion_video" + }, + { + "name": "productlink", + "value": "productlink" + }, + { + "name": "ptt", + "value": "ptt" + }, + { + "name": "ptv", + "value": "ptv" + }, + { + "name": "sticker", + "value": "sticker" + }, + { + "name": "sticker_pack", + "value": "sticker_pack" + }, + { + "name": "url", + "value": "url" + }, + { + "name": "user_created_sticker", + "value": "user_created_sticker" + }, + { + "name": "vcard", + "value": "vcard" + }, + { + "name": "video", + "value": "video" + } + ] + }, "sourcePath": [ "plaintext" ] @@ -1870,7 +2211,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" }, { "method": "", @@ -1884,6 +2226,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -1903,6 +2246,40 @@ "wireName": "message_association_type", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_HDIMAGEDUALUPLOAD_HDVIDEODUALUPLOAD_HEVCVIDEODUALUPLOAD_MEDIAPOLL_MOTIONPHOTO_POLLADDOPTION_STICKERANNOTATION", + "module": "WASmaxInNewslettersEnums", + "variants": [ + { + "name": "hd_image_dual_upload", + "value": "hd_image_dual_upload" + }, + { + "name": "hd_video_dual_upload", + "value": "hd_video_dual_upload" + }, + { + "name": "hevc_video_dual_upload", + "value": "hevc_video_dual_upload" + }, + { + "name": "media_poll", + "value": "media_poll" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "poll_add_option", + "value": "poll_add_option" + }, + { + "name": "sticker_annotation", + "value": "sticker_annotation" + } + ] + }, "sourcePath": [ "meta" ] @@ -1978,7 +2355,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" }, { "method": "", @@ -1992,6 +2370,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -2021,6 +2400,92 @@ "wireName": "mediatype", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_1PSTICKER_AUDIO_AVATARSTICKER_CATALOGLINK_COLLECTION_DOCUMENT_GENAISTICKER_GIF_IMAGE_MOTIONPHOTO_MOTIONVIDEO_PRODUCTLINK_PTT_PTV_STICKER_STICKERPACK_URL_USERCREATEDSTICKER_VCARD_VIDEO", + "module": "WASmaxInNewslettersEnums", + "variants": [ + { + "name": "1p_sticker", + "value": "1p_sticker" + }, + { + "name": "audio", + "value": "audio" + }, + { + "name": "avatar_sticker", + "value": "avatar_sticker" + }, + { + "name": "cataloglink", + "value": "cataloglink" + }, + { + "name": "collection", + "value": "collection" + }, + { + "name": "document", + "value": "document" + }, + { + "name": "genai_sticker", + "value": "genai_sticker" + }, + { + "name": "gif", + "value": "gif" + }, + { + "name": "image", + "value": "image" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "motion_video", + "value": "motion_video" + }, + { + "name": "productlink", + "value": "productlink" + }, + { + "name": "ptt", + "value": "ptt" + }, + { + "name": "ptv", + "value": "ptv" + }, + { + "name": "sticker", + "value": "sticker" + }, + { + "name": "sticker_pack", + "value": "sticker_pack" + }, + { + "name": "url", + "value": "url" + }, + { + "name": "user_created_sticker", + "value": "user_created_sticker" + }, + { + "name": "vcard", + "value": "vcard" + }, + { + "name": "video", + "value": "video" + } + ] + }, "sourcePath": [ "plaintext" ] @@ -2048,7 +2513,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" }, { "method": "", @@ -2062,6 +2528,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -2081,6 +2548,40 @@ "wireName": "message_association_type", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_HDIMAGEDUALUPLOAD_HDVIDEODUALUPLOAD_HEVCVIDEODUALUPLOAD_MEDIAPOLL_MOTIONPHOTO_POLLADDOPTION_STICKERANNOTATION", + "module": "WASmaxInNewslettersEnums", + "variants": [ + { + "name": "hd_image_dual_upload", + "value": "hd_image_dual_upload" + }, + { + "name": "hd_video_dual_upload", + "value": "hd_video_dual_upload" + }, + { + "name": "hevc_video_dual_upload", + "value": "hevc_video_dual_upload" + }, + { + "name": "media_poll", + "value": "media_poll" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "poll_add_option", + "value": "poll_add_option" + }, + { + "name": "sticker_annotation", + "value": "sticker_annotation" + } + ] + }, "sourcePath": [ "meta" ] @@ -2144,6 +2645,7 @@ "wireName": "questiontype", "type": "string", "required": true, + "literalValue": "reply", "sourcePath": [ "meta" ] @@ -2160,6 +2662,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -2199,7 +2702,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" }, { "method": "", @@ -2213,6 +2717,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -2242,6 +2747,92 @@ "wireName": "mediatype", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_1PSTICKER_AUDIO_AVATARSTICKER_CATALOGLINK_COLLECTION_DOCUMENT_GENAISTICKER_GIF_IMAGE_MOTIONPHOTO_MOTIONVIDEO_PRODUCTLINK_PTT_PTV_STICKER_STICKERPACK_URL_USERCREATEDSTICKER_VCARD_VIDEO", + "module": "WASmaxInNewslettersEnums", + "variants": [ + { + "name": "1p_sticker", + "value": "1p_sticker" + }, + { + "name": "audio", + "value": "audio" + }, + { + "name": "avatar_sticker", + "value": "avatar_sticker" + }, + { + "name": "cataloglink", + "value": "cataloglink" + }, + { + "name": "collection", + "value": "collection" + }, + { + "name": "document", + "value": "document" + }, + { + "name": "genai_sticker", + "value": "genai_sticker" + }, + { + "name": "gif", + "value": "gif" + }, + { + "name": "image", + "value": "image" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "motion_video", + "value": "motion_video" + }, + { + "name": "productlink", + "value": "productlink" + }, + { + "name": "ptt", + "value": "ptt" + }, + { + "name": "ptv", + "value": "ptv" + }, + { + "name": "sticker", + "value": "sticker" + }, + { + "name": "sticker_pack", + "value": "sticker_pack" + }, + { + "name": "url", + "value": "url" + }, + { + "name": "user_created_sticker", + "value": "user_created_sticker" + }, + { + "name": "vcard", + "value": "vcard" + }, + { + "name": "video", + "value": "video" + } + ] + }, "sourcePath": [ "plaintext" ] @@ -2269,7 +2860,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" }, { "method": "", @@ -2283,6 +2875,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -2302,6 +2895,40 @@ "wireName": "message_association_type", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_HDIMAGEDUALUPLOAD_HDVIDEODUALUPLOAD_HEVCVIDEODUALUPLOAD_MEDIAPOLL_MOTIONPHOTO_POLLADDOPTION_STICKERANNOTATION", + "module": "WASmaxInNewslettersEnums", + "variants": [ + { + "name": "hd_image_dual_upload", + "value": "hd_image_dual_upload" + }, + { + "name": "hd_video_dual_upload", + "value": "hd_video_dual_upload" + }, + { + "name": "hevc_video_dual_upload", + "value": "hevc_video_dual_upload" + }, + { + "name": "media_poll", + "value": "media_poll" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "poll_add_option", + "value": "poll_add_option" + }, + { + "name": "sticker_annotation", + "value": "sticker_annotation" + } + ] + }, "sourcePath": [ "meta" ] @@ -2359,14 +2986,16 @@ "name": "edit", "wireName": "edit", "type": "string", - "required": true + "required": true, + "literalValue": "8" }, { "method": "attrString", "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" }, { "method": "", @@ -2380,6 +3009,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -2431,7 +3061,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" }, { "method": "", @@ -2445,6 +3076,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -2474,6 +3106,92 @@ "wireName": "mediatype", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_1PSTICKER_AUDIO_AVATARSTICKER_CATALOGLINK_COLLECTION_DOCUMENT_GENAISTICKER_GIF_IMAGE_MOTIONPHOTO_MOTIONVIDEO_PRODUCTLINK_PTT_PTV_STICKER_STICKERPACK_URL_USERCREATEDSTICKER_VCARD_VIDEO", + "module": "WASmaxInNewslettersEnums", + "variants": [ + { + "name": "1p_sticker", + "value": "1p_sticker" + }, + { + "name": "audio", + "value": "audio" + }, + { + "name": "avatar_sticker", + "value": "avatar_sticker" + }, + { + "name": "cataloglink", + "value": "cataloglink" + }, + { + "name": "collection", + "value": "collection" + }, + { + "name": "document", + "value": "document" + }, + { + "name": "genai_sticker", + "value": "genai_sticker" + }, + { + "name": "gif", + "value": "gif" + }, + { + "name": "image", + "value": "image" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "motion_video", + "value": "motion_video" + }, + { + "name": "productlink", + "value": "productlink" + }, + { + "name": "ptt", + "value": "ptt" + }, + { + "name": "ptv", + "value": "ptv" + }, + { + "name": "sticker", + "value": "sticker" + }, + { + "name": "sticker_pack", + "value": "sticker_pack" + }, + { + "name": "url", + "value": "url" + }, + { + "name": "user_created_sticker", + "value": "user_created_sticker" + }, + { + "name": "vcard", + "value": "vcard" + }, + { + "name": "video", + "value": "video" + } + ] + }, "sourcePath": [ "plaintext" ] @@ -2501,7 +3219,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" }, { "method": "", @@ -2515,6 +3234,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -2534,6 +3254,40 @@ "wireName": "message_association_type", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_HDIMAGEDUALUPLOAD_HDVIDEODUALUPLOAD_HEVCVIDEODUALUPLOAD_MEDIAPOLL_MOTIONPHOTO_POLLADDOPTION_STICKERANNOTATION", + "module": "WASmaxInNewslettersEnums", + "variants": [ + { + "name": "hd_image_dual_upload", + "value": "hd_image_dual_upload" + }, + { + "name": "hd_video_dual_upload", + "value": "hd_video_dual_upload" + }, + { + "name": "hevc_video_dual_upload", + "value": "hevc_video_dual_upload" + }, + { + "name": "media_poll", + "value": "media_poll" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "poll_add_option", + "value": "poll_add_option" + }, + { + "name": "sticker_annotation", + "value": "sticker_annotation" + } + ] + }, "sourcePath": [ "meta" ] @@ -2599,7 +3353,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "poll" }, { "method": "attrString", @@ -2607,6 +3362,7 @@ "wireName": "polltype", "type": "string", "required": true, + "literalValue": "creation", "sourcePath": [ "meta" ] @@ -2633,6 +3389,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -2679,7 +3436,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "poll" }, { "method": "attrString", @@ -2687,6 +3445,7 @@ "wireName": "polltype", "type": "string", "required": true, + "literalValue": "quiz_creation", "sourcePath": [ "meta" ] @@ -2713,6 +3472,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -2759,7 +3519,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "poll" }, { "method": "attrString", @@ -2767,6 +3528,7 @@ "wireName": "polltype", "type": "string", "required": true, + "literalValue": "result_snapshot", "sourcePath": [ "meta" ] @@ -2783,6 +3545,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -2812,6 +3575,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -2827,7 +3591,8 @@ "name": "edit", "wireName": "edit", "type": "string", - "required": true + "required": true, + "literalValue": "8" } ], "sameNode": true @@ -2843,7 +3608,8 @@ "name": "edit", "wireName": "edit", "type": "string", - "required": true + "required": true, + "literalValue": "3" } ], "sameNode": true @@ -2863,6 +3629,7 @@ "wireName": "questiontype", "type": "string", "required": true, + "literalValue": "question", "sourcePath": [ "meta" ] @@ -2881,7 +3648,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" } ], "assertions": [ @@ -2904,7 +3672,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" } ], "assertions": [ @@ -2938,6 +3707,7 @@ "wireName": "questiontype", "type": "string", "required": true, + "literalValue": "reply", "sourcePath": [ "meta" ] @@ -2956,7 +3726,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" } ], "assertions": [ @@ -2979,7 +3750,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" } ], "assertions": [ @@ -3012,7 +3784,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" } ], "assertions": [ @@ -3035,7 +3808,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" } ], "assertions": [ @@ -3058,7 +3832,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "poll" }, { "method": "attrString", @@ -3066,6 +3841,7 @@ "wireName": "polltype", "type": "string", "required": true, + "literalValue": "creation", "sourcePath": [ "meta" ] @@ -3101,7 +3877,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "poll" }, { "method": "attrString", @@ -3109,6 +3886,7 @@ "wireName": "polltype", "type": "string", "required": true, + "literalValue": "quiz_creation", "sourcePath": [ "meta" ] @@ -3251,6 +4029,7 @@ "wireName": "mediatype", "type": "string", "required": true, + "literalValue": "url", "sourcePath": [ "plaintext" ] @@ -3269,7 +4048,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" } ], "sameNode": true @@ -3314,7 +4094,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": false + "required": false, + "literalValue": "views" }, { "method": "attrInt", @@ -3378,7 +4159,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "newsletter" }, { "method": "attrInt", @@ -3435,7 +4217,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "psa" }, { "method": "attrInt", @@ -3492,7 +4275,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "psa" }, { "method": "child", @@ -3600,6 +4384,20 @@ "wireName": "dismissable", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInQpSurfacesEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + }, "sourcePath": [ "qp_config" ] @@ -3610,6 +4408,20 @@ "wireName": "force_pass", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInQpSurfacesEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + }, "sourcePath": [ "qp_config" ] @@ -3630,6 +4442,20 @@ "wireName": "deterministic", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInQpSurfacesEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + }, "sourcePath": [ "qp_config" ] @@ -3650,6 +4476,20 @@ "wireName": "exposure_holdout", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInQpSurfacesEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + }, "sourcePath": [ "qp_config" ] @@ -3700,6 +4540,20 @@ "wireName": "log_eligibility_waterfall", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInQpSurfacesEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + }, "sourcePath": [ "qp_config" ] @@ -4117,7 +4971,7 @@ ], "fields": [ { - "method": "attrJidWithType", + "method": "literalJid", "name": "from", "wireName": "from", "type": "jid", @@ -4135,7 +4989,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "business" }, { "method": "maybeAttrString", @@ -4173,6 +5028,20 @@ "wireName": "status", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_INTEGRITYNOTCLEARED_OK", + "module": "WASmaxInSmbMeteredMessagesCampaignEnums", + "variants": [ + { + "name": "INTEGRITY_NOT_CLEARED", + "value": "INTEGRITY_NOT_CLEARED" + }, + { + "name": "OK", + "value": "OK" + } + ] + }, "sourcePath": [ "mm_campaign" ] @@ -4221,7 +5090,7 @@ ], "fields": [ { - "method": "attrJidWithType", + "method": "literalJid", "name": "from", "wireName": "from", "type": "jid", @@ -4232,7 +5101,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "waffle" }, { "method": "attrInt", @@ -4252,6 +5122,20 @@ "wireName": "show_user_notif", "type": "enum", "required": false, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInWaffleEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + }, "sourcePath": [ "notification_metadata" ] @@ -4274,6 +5158,20 @@ "wireName": "client_resync", "type": "enum", "required": false, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInWaffleEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + }, "sourcePath": [ "notification_metadata" ] @@ -4294,6 +5192,20 @@ "wireName": "npr", "type": "enum", "required": false, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInWaffleEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + }, "sourcePath": [ "notification_metadata" ] @@ -4347,7 +5259,7 @@ ], "fields": [ { - "method": "attrJidWithType", + "method": "literalJid", "name": "from", "wireName": "from", "type": "jid", @@ -4358,7 +5270,8 @@ "name": "xmlns", "wireName": "xmlns", "type": "string", - "required": true + "required": true, + "literalValue": "md" }, { "method": "contentBytes", @@ -4400,6 +5313,20 @@ "wireName": "beta", "type": "enum", "required": false, + "enumRef": { + "name": "ENUM_FALSE_TRUE", + "module": "WASmaxInMdEnums", + "variants": [ + { + "name": "false", + "value": "false" + }, + { + "name": "true", + "value": "true" + } + ] + }, "sourcePath": [ "pair-success", "device" @@ -4428,7 +5355,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "set" }, { "method": "child", @@ -4481,14 +5409,16 @@ "name": "version", "wireName": "version", "type": "string", - "required": true + "required": true, + "literalValue": "1" }, { "method": "attrString", "name": "algorithm", "wireName": "algorithm", "type": "string", - "required": true + "required": true, + "literalValue": "aes-256-gcm" }, { "method": "contentBytes", @@ -4566,7 +5496,7 @@ ], "fields": [ { - "method": "attrJidWithType", + "method": "literalJid", "name": "from", "wireName": "from", "type": "jid", @@ -4577,7 +5507,8 @@ "name": "xmlns", "wireName": "xmlns", "type": "string", - "required": true + "required": true, + "literalValue": "md" }, { "method": "attrString", @@ -4591,7 +5522,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "set" }, { "method": "child", @@ -4628,7 +5560,7 @@ ], "fields": [ { - "method": "attrJidWithType", + "method": "literalJid", "name": "from", "wireName": "from", "type": "jid", @@ -4707,7 +5639,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "unavailable" } ], "assertions": [ @@ -4737,14 +5670,33 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "unavailable" }, { "method": "maybeAttrEnum", "name": "last", "wireName": "last", "type": "enum", - "required": false + "required": false, + "enumRef": { + "name": "ENUM_DENY_ERROR_NONE", + "module": "WASmaxInPresenceEnums", + "variants": [ + { + "name": "deny", + "value": "deny" + }, + { + "name": "error", + "value": "error" + }, + { + "name": "none", + "value": "none" + } + ] + } } ], "assertions": [ @@ -4774,7 +5726,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "unavailable" }, { "method": "maybeAttrString", @@ -4811,7 +5764,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": false + "required": false, + "literalValue": "available" }, { "method": "maybeAttrString", @@ -4874,10 +5828,10 @@ "name": "FromUser", "fields": [ { - "method": "attrJidWithType", + "method": "attrJidEnum", "name": "from", "wireName": "from", - "type": "jid", + "type": "jid_typed", "required": true } ], @@ -4899,10 +5853,10 @@ "required": true }, { - "method": "attrJidWithType", + "method": "attrJidEnum", "name": "participant", "wireName": "participant", - "type": "jid", + "type": "jid_typed", "required": true }, { @@ -4937,6 +5891,7 @@ "wireName": "media", "type": "string", "required": false, + "literalValue": "audio", "sourcePath": [ "composing" ] @@ -5005,7 +5960,8 @@ "name": "isSender", "wireName": "is_sender", "type": "string", - "required": false + "required": false, + "literalValue": "true" }, { "method": "", @@ -5140,6 +6096,7 @@ "wireName": "questiontype", "type": "string", "required": true, + "literalValue": "question", "sourcePath": [ "meta" ] @@ -5156,6 +6113,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -5195,7 +6153,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" }, { "method": "", @@ -5209,6 +6168,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -5238,6 +6198,92 @@ "wireName": "mediatype", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_1PSTICKER_AUDIO_AVATARSTICKER_CATALOGLINK_COLLECTION_DOCUMENT_GENAISTICKER_GIF_IMAGE_MOTIONPHOTO_MOTIONVIDEO_PRODUCTLINK_PTT_PTV_STICKER_STICKERPACK_URL_USERCREATEDSTICKER_VCARD_VIDEO", + "module": "WASmaxInMessageDeliverEnums", + "variants": [ + { + "name": "1p_sticker", + "value": "1p_sticker" + }, + { + "name": "audio", + "value": "audio" + }, + { + "name": "avatar_sticker", + "value": "avatar_sticker" + }, + { + "name": "cataloglink", + "value": "cataloglink" + }, + { + "name": "collection", + "value": "collection" + }, + { + "name": "document", + "value": "document" + }, + { + "name": "genai_sticker", + "value": "genai_sticker" + }, + { + "name": "gif", + "value": "gif" + }, + { + "name": "image", + "value": "image" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "motion_video", + "value": "motion_video" + }, + { + "name": "productlink", + "value": "productlink" + }, + { + "name": "ptt", + "value": "ptt" + }, + { + "name": "ptv", + "value": "ptv" + }, + { + "name": "sticker", + "value": "sticker" + }, + { + "name": "sticker_pack", + "value": "sticker_pack" + }, + { + "name": "url", + "value": "url" + }, + { + "name": "user_created_sticker", + "value": "user_created_sticker" + }, + { + "name": "vcard", + "value": "vcard" + }, + { + "name": "video", + "value": "video" + } + ] + }, "sourcePath": [ "plaintext" ] @@ -5265,7 +6311,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" }, { "method": "", @@ -5279,6 +6326,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -5298,6 +6346,40 @@ "wireName": "message_association_type", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_HDIMAGEDUALUPLOAD_HDVIDEODUALUPLOAD_HEVCVIDEODUALUPLOAD_MEDIAPOLL_MOTIONPHOTO_POLLADDOPTION_STICKERANNOTATION", + "module": "WASmaxInMessageDeliverEnums", + "variants": [ + { + "name": "hd_image_dual_upload", + "value": "hd_image_dual_upload" + }, + { + "name": "hd_video_dual_upload", + "value": "hd_video_dual_upload" + }, + { + "name": "hevc_video_dual_upload", + "value": "hevc_video_dual_upload" + }, + { + "name": "media_poll", + "value": "media_poll" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "poll_add_option", + "value": "poll_add_option" + }, + { + "name": "sticker_annotation", + "value": "sticker_annotation" + } + ] + }, "sourcePath": [ "meta" ] @@ -5373,7 +6455,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" }, { "method": "attrString", @@ -5381,6 +6464,7 @@ "wireName": "questiontype", "type": "string", "required": true, + "literalValue": "response", "sourcePath": [ "meta" ] @@ -5416,7 +6500,8 @@ "name": "edit", "wireName": "edit", "type": "string", - "required": true + "required": true, + "literalValue": "3" }, { "method": "", @@ -5430,6 +6515,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -5452,6 +6538,7 @@ "wireName": "questiontype", "type": "string", "required": true, + "literalValue": "reply", "sourcePath": [ "meta" ] @@ -5468,6 +6555,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -5507,7 +6595,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" }, { "method": "", @@ -5521,6 +6610,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -5550,6 +6640,92 @@ "wireName": "mediatype", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_1PSTICKER_AUDIO_AVATARSTICKER_CATALOGLINK_COLLECTION_DOCUMENT_GENAISTICKER_GIF_IMAGE_MOTIONPHOTO_MOTIONVIDEO_PRODUCTLINK_PTT_PTV_STICKER_STICKERPACK_URL_USERCREATEDSTICKER_VCARD_VIDEO", + "module": "WASmaxInMessageDeliverEnums", + "variants": [ + { + "name": "1p_sticker", + "value": "1p_sticker" + }, + { + "name": "audio", + "value": "audio" + }, + { + "name": "avatar_sticker", + "value": "avatar_sticker" + }, + { + "name": "cataloglink", + "value": "cataloglink" + }, + { + "name": "collection", + "value": "collection" + }, + { + "name": "document", + "value": "document" + }, + { + "name": "genai_sticker", + "value": "genai_sticker" + }, + { + "name": "gif", + "value": "gif" + }, + { + "name": "image", + "value": "image" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "motion_video", + "value": "motion_video" + }, + { + "name": "productlink", + "value": "productlink" + }, + { + "name": "ptt", + "value": "ptt" + }, + { + "name": "ptv", + "value": "ptv" + }, + { + "name": "sticker", + "value": "sticker" + }, + { + "name": "sticker_pack", + "value": "sticker_pack" + }, + { + "name": "url", + "value": "url" + }, + { + "name": "user_created_sticker", + "value": "user_created_sticker" + }, + { + "name": "vcard", + "value": "vcard" + }, + { + "name": "video", + "value": "video" + } + ] + }, "sourcePath": [ "plaintext" ] @@ -5577,7 +6753,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" }, { "method": "", @@ -5591,6 +6768,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -5610,6 +6788,40 @@ "wireName": "message_association_type", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_HDIMAGEDUALUPLOAD_HDVIDEODUALUPLOAD_HEVCVIDEODUALUPLOAD_MEDIAPOLL_MOTIONPHOTO_POLLADDOPTION_STICKERANNOTATION", + "module": "WASmaxInMessageDeliverEnums", + "variants": [ + { + "name": "hd_image_dual_upload", + "value": "hd_image_dual_upload" + }, + { + "name": "hd_video_dual_upload", + "value": "hd_video_dual_upload" + }, + { + "name": "hevc_video_dual_upload", + "value": "hevc_video_dual_upload" + }, + { + "name": "media_poll", + "value": "media_poll" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "poll_add_option", + "value": "poll_add_option" + }, + { + "name": "sticker_annotation", + "value": "sticker_annotation" + } + ] + }, "sourcePath": [ "meta" ] @@ -5685,7 +6897,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" }, { "method": "", @@ -5699,6 +6912,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -5728,6 +6942,92 @@ "wireName": "mediatype", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_1PSTICKER_AUDIO_AVATARSTICKER_CATALOGLINK_COLLECTION_DOCUMENT_GENAISTICKER_GIF_IMAGE_MOTIONPHOTO_MOTIONVIDEO_PRODUCTLINK_PTT_PTV_STICKER_STICKERPACK_URL_USERCREATEDSTICKER_VCARD_VIDEO", + "module": "WASmaxInMessageDeliverEnums", + "variants": [ + { + "name": "1p_sticker", + "value": "1p_sticker" + }, + { + "name": "audio", + "value": "audio" + }, + { + "name": "avatar_sticker", + "value": "avatar_sticker" + }, + { + "name": "cataloglink", + "value": "cataloglink" + }, + { + "name": "collection", + "value": "collection" + }, + { + "name": "document", + "value": "document" + }, + { + "name": "genai_sticker", + "value": "genai_sticker" + }, + { + "name": "gif", + "value": "gif" + }, + { + "name": "image", + "value": "image" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "motion_video", + "value": "motion_video" + }, + { + "name": "productlink", + "value": "productlink" + }, + { + "name": "ptt", + "value": "ptt" + }, + { + "name": "ptv", + "value": "ptv" + }, + { + "name": "sticker", + "value": "sticker" + }, + { + "name": "sticker_pack", + "value": "sticker_pack" + }, + { + "name": "url", + "value": "url" + }, + { + "name": "user_created_sticker", + "value": "user_created_sticker" + }, + { + "name": "vcard", + "value": "vcard" + }, + { + "name": "video", + "value": "video" + } + ] + }, "sourcePath": [ "plaintext" ] @@ -5755,7 +7055,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" }, { "method": "", @@ -5769,6 +7070,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -5788,6 +7090,40 @@ "wireName": "message_association_type", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_HDIMAGEDUALUPLOAD_HDVIDEODUALUPLOAD_HEVCVIDEODUALUPLOAD_MEDIAPOLL_MOTIONPHOTO_POLLADDOPTION_STICKERANNOTATION", + "module": "WASmaxInMessageDeliverEnums", + "variants": [ + { + "name": "hd_image_dual_upload", + "value": "hd_image_dual_upload" + }, + { + "name": "hd_video_dual_upload", + "value": "hd_video_dual_upload" + }, + { + "name": "hevc_video_dual_upload", + "value": "hevc_video_dual_upload" + }, + { + "name": "media_poll", + "value": "media_poll" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "poll_add_option", + "value": "poll_add_option" + }, + { + "name": "sticker_annotation", + "value": "sticker_annotation" + } + ] + }, "sourcePath": [ "meta" ] @@ -5851,6 +7187,7 @@ "wireName": "questiontype", "type": "string", "required": true, + "literalValue": "reply", "sourcePath": [ "meta" ] @@ -5867,6 +7204,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -5906,7 +7244,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" }, { "method": "", @@ -5920,6 +7259,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -5949,6 +7289,92 @@ "wireName": "mediatype", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_1PSTICKER_AUDIO_AVATARSTICKER_CATALOGLINK_COLLECTION_DOCUMENT_GENAISTICKER_GIF_IMAGE_MOTIONPHOTO_MOTIONVIDEO_PRODUCTLINK_PTT_PTV_STICKER_STICKERPACK_URL_USERCREATEDSTICKER_VCARD_VIDEO", + "module": "WASmaxInMessageDeliverEnums", + "variants": [ + { + "name": "1p_sticker", + "value": "1p_sticker" + }, + { + "name": "audio", + "value": "audio" + }, + { + "name": "avatar_sticker", + "value": "avatar_sticker" + }, + { + "name": "cataloglink", + "value": "cataloglink" + }, + { + "name": "collection", + "value": "collection" + }, + { + "name": "document", + "value": "document" + }, + { + "name": "genai_sticker", + "value": "genai_sticker" + }, + { + "name": "gif", + "value": "gif" + }, + { + "name": "image", + "value": "image" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "motion_video", + "value": "motion_video" + }, + { + "name": "productlink", + "value": "productlink" + }, + { + "name": "ptt", + "value": "ptt" + }, + { + "name": "ptv", + "value": "ptv" + }, + { + "name": "sticker", + "value": "sticker" + }, + { + "name": "sticker_pack", + "value": "sticker_pack" + }, + { + "name": "url", + "value": "url" + }, + { + "name": "user_created_sticker", + "value": "user_created_sticker" + }, + { + "name": "vcard", + "value": "vcard" + }, + { + "name": "video", + "value": "video" + } + ] + }, "sourcePath": [ "plaintext" ] @@ -5976,7 +7402,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" }, { "method": "", @@ -5990,6 +7417,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -6009,6 +7437,40 @@ "wireName": "message_association_type", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_HDIMAGEDUALUPLOAD_HDVIDEODUALUPLOAD_HEVCVIDEODUALUPLOAD_MEDIAPOLL_MOTIONPHOTO_POLLADDOPTION_STICKERANNOTATION", + "module": "WASmaxInMessageDeliverEnums", + "variants": [ + { + "name": "hd_image_dual_upload", + "value": "hd_image_dual_upload" + }, + { + "name": "hd_video_dual_upload", + "value": "hd_video_dual_upload" + }, + { + "name": "hevc_video_dual_upload", + "value": "hevc_video_dual_upload" + }, + { + "name": "media_poll", + "value": "media_poll" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "poll_add_option", + "value": "poll_add_option" + }, + { + "name": "sticker_annotation", + "value": "sticker_annotation" + } + ] + }, "sourcePath": [ "meta" ] @@ -6066,14 +7528,16 @@ "name": "edit", "wireName": "edit", "type": "string", - "required": true + "required": true, + "literalValue": "8" }, { "method": "attrString", "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" }, { "method": "", @@ -6087,6 +7551,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -6138,7 +7603,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" }, { "method": "", @@ -6152,6 +7618,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -6181,6 +7648,92 @@ "wireName": "mediatype", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_1PSTICKER_AUDIO_AVATARSTICKER_CATALOGLINK_COLLECTION_DOCUMENT_GENAISTICKER_GIF_IMAGE_MOTIONPHOTO_MOTIONVIDEO_PRODUCTLINK_PTT_PTV_STICKER_STICKERPACK_URL_USERCREATEDSTICKER_VCARD_VIDEO", + "module": "WASmaxInMessageDeliverEnums", + "variants": [ + { + "name": "1p_sticker", + "value": "1p_sticker" + }, + { + "name": "audio", + "value": "audio" + }, + { + "name": "avatar_sticker", + "value": "avatar_sticker" + }, + { + "name": "cataloglink", + "value": "cataloglink" + }, + { + "name": "collection", + "value": "collection" + }, + { + "name": "document", + "value": "document" + }, + { + "name": "genai_sticker", + "value": "genai_sticker" + }, + { + "name": "gif", + "value": "gif" + }, + { + "name": "image", + "value": "image" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "motion_video", + "value": "motion_video" + }, + { + "name": "productlink", + "value": "productlink" + }, + { + "name": "ptt", + "value": "ptt" + }, + { + "name": "ptv", + "value": "ptv" + }, + { + "name": "sticker", + "value": "sticker" + }, + { + "name": "sticker_pack", + "value": "sticker_pack" + }, + { + "name": "url", + "value": "url" + }, + { + "name": "user_created_sticker", + "value": "user_created_sticker" + }, + { + "name": "vcard", + "value": "vcard" + }, + { + "name": "video", + "value": "video" + } + ] + }, "sourcePath": [ "plaintext" ] @@ -6208,7 +7761,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" }, { "method": "", @@ -6222,6 +7776,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -6241,6 +7796,40 @@ "wireName": "message_association_type", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_HDIMAGEDUALUPLOAD_HDVIDEODUALUPLOAD_HEVCVIDEODUALUPLOAD_MEDIAPOLL_MOTIONPHOTO_POLLADDOPTION_STICKERANNOTATION", + "module": "WASmaxInMessageDeliverEnums", + "variants": [ + { + "name": "hd_image_dual_upload", + "value": "hd_image_dual_upload" + }, + { + "name": "hd_video_dual_upload", + "value": "hd_video_dual_upload" + }, + { + "name": "hevc_video_dual_upload", + "value": "hevc_video_dual_upload" + }, + { + "name": "media_poll", + "value": "media_poll" + }, + { + "name": "motion_photo", + "value": "motion_photo" + }, + { + "name": "poll_add_option", + "value": "poll_add_option" + }, + { + "name": "sticker_annotation", + "value": "sticker_annotation" + } + ] + }, "sourcePath": [ "meta" ] @@ -6298,7 +7887,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "reaction" } ], "assertions": [ @@ -6321,14 +7911,16 @@ "name": "edit", "wireName": "edit", "type": "string", - "required": true + "required": true, + "literalValue": "7" }, { "method": "attrString", "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "reaction" } ], "assertions": [ @@ -6374,7 +7966,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "poll" }, { "method": "attrString", @@ -6382,6 +7975,7 @@ "wireName": "polltype", "type": "string", "required": true, + "literalValue": "creation", "sourcePath": [ "meta" ] @@ -6408,6 +8002,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -6454,7 +8049,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "poll" }, { "method": "attrString", @@ -6462,6 +8058,7 @@ "wireName": "polltype", "type": "string", "required": true, + "literalValue": "quiz_creation", "sourcePath": [ "meta" ] @@ -6488,6 +8085,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -6516,7 +8114,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "poll" }, { "method": "attrString", @@ -6524,6 +8123,7 @@ "wireName": "polltype", "type": "string", "required": true, + "literalValue": "vote", "sourcePath": [ "meta" ] @@ -6597,7 +8197,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "poll" }, { "method": "attrString", @@ -6605,6 +8206,7 @@ "wireName": "polltype", "type": "string", "required": true, + "literalValue": "result_snapshot", "sourcePath": [ "meta" ] @@ -6621,6 +8223,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -6650,6 +8253,7 @@ "wireName": "is_wamo_sub", "type": "string", "required": true, + "literalValue": "true", "sourcePath": [ "meta" ] @@ -6665,7 +8269,8 @@ "name": "edit", "wireName": "edit", "type": "string", - "required": true + "required": true, + "literalValue": "8" } ], "sameNode": true @@ -6681,7 +8286,8 @@ "name": "edit", "wireName": "edit", "type": "string", - "required": true + "required": true, + "literalValue": "3" } ], "sameNode": true @@ -6701,6 +8307,7 @@ "wireName": "questiontype", "type": "string", "required": true, + "literalValue": "question", "sourcePath": [ "meta" ] @@ -6719,7 +8326,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" } ], "assertions": [ @@ -6742,7 +8350,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" } ], "assertions": [ @@ -6776,6 +8385,7 @@ "wireName": "questiontype", "type": "string", "required": true, + "literalValue": "reply", "sourcePath": [ "meta" ] @@ -6794,7 +8404,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" } ], "assertions": [ @@ -6817,7 +8428,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" } ], "assertions": [ @@ -6850,7 +8462,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" } ], "assertions": [ @@ -6873,7 +8486,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" } ], "assertions": [ @@ -6896,7 +8510,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "poll" }, { "method": "attrString", @@ -6904,6 +8519,7 @@ "wireName": "polltype", "type": "string", "required": true, + "literalValue": "creation", "sourcePath": [ "meta" ] @@ -6939,7 +8555,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "poll" }, { "method": "attrString", @@ -6947,6 +8564,7 @@ "wireName": "polltype", "type": "string", "required": true, + "literalValue": "quiz_creation", "sourcePath": [ "meta" ] @@ -7034,6 +8652,7 @@ "wireName": "mediatype", "type": "string", "required": true, + "literalValue": "url", "sourcePath": [ "plaintext" ] @@ -7052,7 +8671,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" } ], "sameNode": true @@ -7107,7 +8727,8 @@ "name": "isSender", "wireName": "is_sender", "type": "string", - "required": false + "required": false, + "literalValue": "true" }, { "method": "", @@ -7123,14 +8744,16 @@ "name": "edit", "wireName": "edit", "type": "string", - "required": true + "required": true, + "literalValue": "8" }, { "method": "attrString", "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" } ], "assertions": [ @@ -7176,7 +8799,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "text" } ], "assertions": [ @@ -7200,6 +8824,28 @@ "wireName": "mediatype", "type": "enum", "required": true, + "enumRef": { + "name": "ENUM_AUDIO_GIF_IMAGE_VIDEO", + "module": "WASmaxInStatusDeliverEnums", + "variants": [ + { + "name": "audio", + "value": "audio" + }, + { + "name": "gif", + "value": "gif" + }, + { + "name": "image", + "value": "image" + }, + { + "name": "video", + "value": "video" + } + ] + }, "sourcePath": [ "plaintext" ] @@ -7227,7 +8873,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "media" } ], "assertions": [ @@ -7260,7 +8907,8 @@ "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "reaction" } ], "assertions": [ @@ -7283,14 +8931,16 @@ "name": "edit", "wireName": "edit", "type": "string", - "required": true + "required": true, + "literalValue": "7" }, { "method": "attrString", "name": "type", "wireName": "type", "type": "string", - "required": true + "required": true, + "literalValue": "reaction" } ], "assertions": [ diff --git a/generated/stanza/index.json b/generated/stanza/index.json index 779abce..4069e15 100644 --- a/generated/stanza/index.json +++ b/generated/stanza/index.json @@ -1,5 +1,5 @@ { - "schemaVersion": "1.0.0", + "schemaVersion": "2.0.0", "waVersion": "2.3000.1043899084", "stanzas": [ { diff --git a/generated/tokens/index.json b/generated/tokens/index.json index ff0a9d7..5d1b4bd 100644 --- a/generated/tokens/index.json +++ b/generated/tokens/index.json @@ -1,5 +1,5 @@ { - "schemaVersion": "1.0.0", + "schemaVersion": "2.0.0", "waVersion": "2.3000.1043899084", "dictVersion": 3, "singleByte": [ diff --git a/generated/wam/index.json b/generated/wam/index.json index d695609..6791d3e 100644 --- a/generated/wam/index.json +++ b/generated/wam/index.json @@ -1,5 +1,5 @@ { - "schemaVersion": "1.0.0", + "schemaVersion": "2.0.0", "waVersion": "2.3000.1043899084", "events": [ { diff --git a/generated/wasm/index.json b/generated/wasm/index.json index 2d4a769..96d4c6c 100644 --- a/generated/wasm/index.json +++ b/generated/wasm/index.json @@ -1,5 +1,5 @@ { - "schemaVersion": "1.0.0", + "schemaVersion": "2.0.0", "waVersion": "2.3000.1043899084", "binaries": [ {