@mattstack/rt-client 0.29.0 → 0.30.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands.d.ts +1 -0
- package/dist/gate-answers.d.ts +3 -2
- package/dist/gate.js +13 -6
- package/dist/index.js +13 -6
- package/package.json +1 -1
- package/src/commands.ts +1 -1
- package/src/gate-answers.ts +12 -7
package/dist/commands.d.ts
CHANGED
package/dist/gate-answers.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { GateQuestion, GateAnswer } from "./commands.ts";
|
|
2
2
|
export type GateAnswerWire = GateAnswer["answers"][string];
|
|
3
|
-
/** Both wire shapes carry the same value underneath: bare, or {value,
|
|
4
|
-
when a panel attaches free text
|
|
3
|
+
/** Both wire shapes carry the same value underneath: bare, or {value,
|
|
4
|
+
note?, text?} when a panel attaches free text or a replacement for text
|
|
5
|
+
the gate offered. Unwrapping keeps only the value. */
|
|
5
6
|
export declare function unwrapGateAnswerValue(raw: unknown): unknown;
|
|
6
7
|
/** Option membership is required whenever a question declares options,
|
|
7
8
|
checked against the unwrapped value (every element, for multi); an
|
package/dist/gate.js
CHANGED
|
@@ -54,12 +54,18 @@ function unwrapGateAnswerValue(raw) {
|
|
|
54
54
|
}
|
|
55
55
|
return raw;
|
|
56
56
|
}
|
|
57
|
-
function
|
|
57
|
+
function wrapperFieldError(qid, raw) {
|
|
58
58
|
if (!raw || typeof raw !== "object" || Array.isArray(raw) || !("value" in raw)) {
|
|
59
|
-
return
|
|
59
|
+
return null;
|
|
60
60
|
}
|
|
61
|
-
const note = raw
|
|
62
|
-
|
|
61
|
+
const { note, text } = raw;
|
|
62
|
+
if (note !== undefined && typeof note !== "string")
|
|
63
|
+
return `question ${qid} note must be a string`;
|
|
64
|
+
if (text !== undefined && typeof text !== "string")
|
|
65
|
+
return `question ${qid} text must be a string`;
|
|
66
|
+
if (typeof text === "string" && text.trim() === "")
|
|
67
|
+
return `question ${qid} text must not be empty`;
|
|
68
|
+
return null;
|
|
63
69
|
}
|
|
64
70
|
function validateGateAnswers(questions, answers) {
|
|
65
71
|
const byId = new Map(questions.map((q) => [q.id, q]));
|
|
@@ -67,8 +73,9 @@ function validateGateAnswers(questions, answers) {
|
|
|
67
73
|
const question = byId.get(qid);
|
|
68
74
|
if (!question)
|
|
69
75
|
return `unknown question id: ${qid}`;
|
|
70
|
-
|
|
71
|
-
|
|
76
|
+
const wrapperError = wrapperFieldError(qid, raw);
|
|
77
|
+
if (wrapperError)
|
|
78
|
+
return wrapperError;
|
|
72
79
|
const value = unwrapGateAnswerValue(raw);
|
|
73
80
|
const isArray = Array.isArray(value);
|
|
74
81
|
if (question.multi && !isArray)
|
package/dist/index.js
CHANGED
|
@@ -643,12 +643,18 @@ function unwrapGateAnswerValue(raw) {
|
|
|
643
643
|
}
|
|
644
644
|
return raw;
|
|
645
645
|
}
|
|
646
|
-
function
|
|
646
|
+
function wrapperFieldError(qid, raw) {
|
|
647
647
|
if (!raw || typeof raw !== "object" || Array.isArray(raw) || !("value" in raw)) {
|
|
648
|
-
return
|
|
648
|
+
return null;
|
|
649
649
|
}
|
|
650
|
-
const note = raw
|
|
651
|
-
|
|
650
|
+
const { note, text } = raw;
|
|
651
|
+
if (note !== undefined && typeof note !== "string")
|
|
652
|
+
return `question ${qid} note must be a string`;
|
|
653
|
+
if (text !== undefined && typeof text !== "string")
|
|
654
|
+
return `question ${qid} text must be a string`;
|
|
655
|
+
if (typeof text === "string" && text.trim() === "")
|
|
656
|
+
return `question ${qid} text must not be empty`;
|
|
657
|
+
return null;
|
|
652
658
|
}
|
|
653
659
|
function validateGateAnswers(questions, answers) {
|
|
654
660
|
const byId = new Map(questions.map((q) => [q.id, q]));
|
|
@@ -656,8 +662,9 @@ function validateGateAnswers(questions, answers) {
|
|
|
656
662
|
const question = byId.get(qid);
|
|
657
663
|
if (!question)
|
|
658
664
|
return `unknown question id: ${qid}`;
|
|
659
|
-
|
|
660
|
-
|
|
665
|
+
const wrapperError = wrapperFieldError(qid, raw);
|
|
666
|
+
if (wrapperError)
|
|
667
|
+
return wrapperError;
|
|
661
668
|
const value = unwrapGateAnswerValue(raw);
|
|
662
669
|
const isArray = Array.isArray(value);
|
|
663
670
|
if (question.multi && !isArray)
|
package/package.json
CHANGED
package/src/commands.ts
CHANGED
|
@@ -133,7 +133,7 @@ export { gateOptionValue, gateOptionLabel } from "./gate-options.ts";
|
|
|
133
133
|
doorbell it would otherwise send back to the writer. Optional: a caller
|
|
134
134
|
that supplies none (the board status-bin answers `by: "pane"` with no
|
|
135
135
|
session) still matches self by `by === GATE_BY_PANE`. */
|
|
136
|
-
export interface GateAnswer { answers: Record<string, string | string[] | { value: string | string[]; note?: string }>; by: string; answeredAt: number; overridden?: boolean; session?: string }
|
|
136
|
+
export interface GateAnswer { answers: Record<string, string | string[] | { value: string | string[]; note?: string; text?: string }>; by: string; answeredAt: number; overridden?: boolean; session?: string }
|
|
137
137
|
export interface GateRow {
|
|
138
138
|
id: string; subject: string; kind: string;
|
|
139
139
|
questions: GateQuestion[]; meta: Record<string, unknown> | null;
|
package/src/gate-answers.ts
CHANGED
|
@@ -3,8 +3,9 @@ import { gateOptionValue } from "./gate-options.ts";
|
|
|
3
3
|
|
|
4
4
|
export type GateAnswerWire = GateAnswer["answers"][string];
|
|
5
5
|
|
|
6
|
-
/** Both wire shapes carry the same value underneath: bare, or {value,
|
|
7
|
-
when a panel attaches free text
|
|
6
|
+
/** Both wire shapes carry the same value underneath: bare, or {value,
|
|
7
|
+
note?, text?} when a panel attaches free text or a replacement for text
|
|
8
|
+
the gate offered. Unwrapping keeps only the value. */
|
|
8
9
|
export function unwrapGateAnswerValue(raw: unknown): unknown {
|
|
9
10
|
if (raw && typeof raw === "object" && !Array.isArray(raw) && "value" in (raw as Record<string, unknown>)) {
|
|
10
11
|
return (raw as { value: unknown }).value;
|
|
@@ -12,12 +13,15 @@ export function unwrapGateAnswerValue(raw: unknown): unknown {
|
|
|
12
13
|
return raw;
|
|
13
14
|
}
|
|
14
15
|
|
|
15
|
-
function
|
|
16
|
+
function wrapperFieldError(qid: string, raw: unknown): string | null {
|
|
16
17
|
if (!raw || typeof raw !== "object" || Array.isArray(raw) || !("value" in (raw as Record<string, unknown>))) {
|
|
17
|
-
return
|
|
18
|
+
return null;
|
|
18
19
|
}
|
|
19
|
-
const note =
|
|
20
|
-
|
|
20
|
+
const { note, text } = raw as Record<string, unknown>;
|
|
21
|
+
if (note !== undefined && typeof note !== "string") return `question ${qid} note must be a string`;
|
|
22
|
+
if (text !== undefined && typeof text !== "string") return `question ${qid} text must be a string`;
|
|
23
|
+
if (typeof text === "string" && text.trim() === "") return `question ${qid} text must not be empty`;
|
|
24
|
+
return null;
|
|
21
25
|
}
|
|
22
26
|
|
|
23
27
|
/** Option membership is required whenever a question declares options,
|
|
@@ -32,7 +36,8 @@ export function validateGateAnswers(
|
|
|
32
36
|
for (const [qid, raw] of Object.entries(answers)) {
|
|
33
37
|
const question = byId.get(qid);
|
|
34
38
|
if (!question) return `unknown question id: ${qid}`;
|
|
35
|
-
|
|
39
|
+
const wrapperError = wrapperFieldError(qid, raw);
|
|
40
|
+
if (wrapperError) return wrapperError;
|
|
36
41
|
const value = unwrapGateAnswerValue(raw);
|
|
37
42
|
const isArray = Array.isArray(value);
|
|
38
43
|
if (question.multi && !isArray) return `question ${qid} expects an array (multi)`;
|