@go-labs-sg/bb 2.48.0 → 3.1.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/README.md +131 -15
- package/command-manifest.json +3149 -563
- package/command-reference.md +359 -31
- package/dist/index.js +2604 -753
- package/package.json +2 -2
- package/role-aware-agent-guide.md +7 -0
package/dist/index.js
CHANGED
|
@@ -35,31 +35,31 @@ var __toESM = (mod, isNodeMode, target) => {
|
|
|
35
35
|
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
36
36
|
var __require = import.meta.require;
|
|
37
37
|
|
|
38
|
-
// ../../../node_modules/.bun/dotenv@18.0.
|
|
38
|
+
// ../../../node_modules/.bun/dotenv@18.0.8/node_modules/dotenv/dist/index.cjs
|
|
39
39
|
var require_dist = __commonJS(function(exports, module) {
|
|
40
|
-
var
|
|
40
|
+
var j = (e, n) => () => {
|
|
41
41
|
try {
|
|
42
|
-
return
|
|
42
|
+
return n || e((n = { exports: {} }).exports, n), n.exports;
|
|
43
43
|
} catch (t) {
|
|
44
|
-
throw
|
|
44
|
+
throw n = 0, t;
|
|
45
45
|
}
|
|
46
46
|
};
|
|
47
|
-
var
|
|
47
|
+
var k = j((xe, U) => {
|
|
48
48
|
function G(e) {
|
|
49
49
|
return typeof e == "string" ? !["false", "0", "no", "off", ""].includes(e.toLowerCase()) : !!e;
|
|
50
50
|
}
|
|
51
|
-
function
|
|
52
|
-
let
|
|
51
|
+
function Y(e = process.env) {
|
|
52
|
+
let n = {};
|
|
53
53
|
for (let t of ["ENCODING", "PATH", "QUIET", "DEBUG", "OVERRIDE", "FAST"]) {
|
|
54
|
-
let
|
|
55
|
-
|
|
54
|
+
let o = e[`DOTENV_${t}`] != null ? e[`DOTENV_${t}`] : e[`DOTENV_CONFIG_${t}`];
|
|
55
|
+
o != null && (n[t.toLowerCase()] = t === "ENCODING" || t === "PATH" ? o : G(o));
|
|
56
56
|
}
|
|
57
|
-
return
|
|
57
|
+
return n;
|
|
58
58
|
}
|
|
59
|
-
U.exports = { parseBoolean: G, optionsFromEnv:
|
|
59
|
+
U.exports = { parseBoolean: G, optionsFromEnv: Y };
|
|
60
60
|
});
|
|
61
|
-
var N =
|
|
62
|
-
var
|
|
61
|
+
var N = j((ye, x) => {
|
|
62
|
+
var z = __require("fs"), I = __require("path"), Z = __require("os"), { URL: ee, fileURLToPath: te } = __require("url"), { parseBoolean: $, optionsFromEnv: B } = k(), re = /(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg, b = new Uint8Array(256);
|
|
63
63
|
for (let e = 48;e <= 57; e++)
|
|
64
64
|
b[e] = 1;
|
|
65
65
|
for (let e = 65;e <= 90; e++)
|
|
@@ -69,92 +69,92 @@ var require_dist = __commonJS(function(exports, module) {
|
|
|
69
69
|
b[45] = 1;
|
|
70
70
|
b[46] = 1;
|
|
71
71
|
b[95] = 1;
|
|
72
|
-
function
|
|
73
|
-
let
|
|
72
|
+
function ne(e) {
|
|
73
|
+
let n = {}, t = e.toString();
|
|
74
74
|
t = t.replace(/\r\n?/mg, `
|
|
75
75
|
`);
|
|
76
|
-
let
|
|
77
|
-
for (;(
|
|
78
|
-
let r =
|
|
76
|
+
let o;
|
|
77
|
+
for (;(o = re.exec(t)) != null; ) {
|
|
78
|
+
let r = o[1], s = o[2] || "";
|
|
79
79
|
s = s.trim();
|
|
80
80
|
let i = s[0];
|
|
81
81
|
s = s.replace(/^(['"`])([\s\S]*)\1$/mg, "$2"), i === '"' && (s = s.replace(/\\n/g, `
|
|
82
|
-
`), s = s.replace(/\\r/g, "\r")),
|
|
82
|
+
`), s = s.replace(/\\r/g, "\r")), n[r] = s;
|
|
83
83
|
}
|
|
84
|
-
return
|
|
84
|
+
return n;
|
|
85
85
|
}
|
|
86
86
|
function w(e) {
|
|
87
87
|
return e <= 32 ? e === 32 || e >= 9 && e <= 13 : e >= 160 && (e === 160 || e === 5760 || e >= 8192 && e <= 8202 || e === 8232 || e === 8233 || e === 8239 || e === 8287 || e === 12288 || e === 65279);
|
|
88
88
|
}
|
|
89
|
-
function
|
|
89
|
+
function q(e) {
|
|
90
90
|
return e === 10 || e === 8232 || e === 8233;
|
|
91
91
|
}
|
|
92
92
|
function oe(e) {
|
|
93
|
-
let
|
|
93
|
+
let n = {}, t = typeof e == "string" ? e : e.toString();
|
|
94
94
|
t.indexOf("\r") !== -1 && (t = t.replace(/\r\n?/g, `
|
|
95
95
|
`));
|
|
96
|
-
let
|
|
97
|
-
for (;r <
|
|
96
|
+
let o = t.length, r = 0;
|
|
97
|
+
for (;r < o; ) {
|
|
98
98
|
let s = t.charCodeAt(r);
|
|
99
|
-
for (;r <
|
|
99
|
+
for (;r < o && w(s); )
|
|
100
100
|
r++, s = t.charCodeAt(r);
|
|
101
|
-
if (r >=
|
|
101
|
+
if (r >= o)
|
|
102
102
|
break;
|
|
103
103
|
if (s === 35) {
|
|
104
|
-
for (;r <
|
|
104
|
+
for (;r < o && !q(t.charCodeAt(r)); )
|
|
105
105
|
r++;
|
|
106
106
|
continue;
|
|
107
107
|
}
|
|
108
108
|
let i = -1;
|
|
109
|
-
if (s === 101 && r + 6 <
|
|
109
|
+
if (s === 101 && r + 6 < o && t.charCodeAt(r + 1) === 120 && t.charCodeAt(r + 2) === 112 && t.charCodeAt(r + 3) === 111 && t.charCodeAt(r + 4) === 114 && t.charCodeAt(r + 5) === 116) {
|
|
110
110
|
let v = t.charCodeAt(r + 6);
|
|
111
111
|
if (w(v)) {
|
|
112
112
|
let u = r + 7;
|
|
113
|
-
for (;u <
|
|
113
|
+
for (;u < o && w(t.charCodeAt(u)); )
|
|
114
114
|
u++;
|
|
115
115
|
b[t.charCodeAt(u)] && (i = r + 6, r = u);
|
|
116
116
|
} else
|
|
117
117
|
s = t.charCodeAt(r);
|
|
118
118
|
}
|
|
119
119
|
let l = r, d = 0;
|
|
120
|
-
for (;r <
|
|
120
|
+
for (;r < o && (d = t.charCodeAt(r), b[d]); )
|
|
121
121
|
r++;
|
|
122
122
|
if (r === l) {
|
|
123
|
-
for (;r <
|
|
123
|
+
for (;r < o && !q(t.charCodeAt(r)); )
|
|
124
124
|
r++;
|
|
125
125
|
continue;
|
|
126
126
|
}
|
|
127
|
-
let
|
|
128
|
-
if (r >=
|
|
127
|
+
let h = t.slice(l, r), f = r;
|
|
128
|
+
if (r >= o && (d = 0), w(d))
|
|
129
129
|
do
|
|
130
|
-
r++, d = r <
|
|
130
|
+
r++, d = r < o ? t.charCodeAt(r) : 0;
|
|
131
131
|
while (w(d));
|
|
132
132
|
if (d === 61)
|
|
133
133
|
r++;
|
|
134
|
-
else if (d === 58 && r === f && r + 1 <
|
|
134
|
+
else if (d === 58 && r === f && r + 1 < o && w(t.charCodeAt(r + 1)))
|
|
135
135
|
r += 2;
|
|
136
136
|
else {
|
|
137
|
-
for (r = i === -1 ? f : i;r <
|
|
137
|
+
for (r = i === -1 ? f : i;r < o && !q(t.charCodeAt(r)); )
|
|
138
138
|
r++;
|
|
139
139
|
continue;
|
|
140
140
|
}
|
|
141
141
|
let c = r, a = r;
|
|
142
|
-
for (;a <
|
|
142
|
+
for (;a < o && w(t.charCodeAt(a)); )
|
|
143
143
|
a++;
|
|
144
|
-
let g = t.charCodeAt(a),
|
|
144
|
+
let g = t.charCodeAt(a), p, y = false;
|
|
145
145
|
if (g === 39 || g === 34 || g === 96) {
|
|
146
146
|
let v = t[a], u = t.indexOf(v, a + 1), m = -1, C = -1;
|
|
147
147
|
for (;u !== -1; ) {
|
|
148
|
-
let
|
|
149
|
-
for (;E <
|
|
148
|
+
let O = t.charCodeAt(u - 1) === 92, E = u + 1;
|
|
149
|
+
for (;E < o && !q(t.charCodeAt(E)) && w(t.charCodeAt(E)); )
|
|
150
150
|
E++;
|
|
151
|
-
if ((E ===
|
|
151
|
+
if ((E === o || q(t.charCodeAt(E)) || t.charCodeAt(E) === 35) && (m = u, C = E), !O)
|
|
152
152
|
break;
|
|
153
153
|
u = t.indexOf(v, u + 1);
|
|
154
154
|
}
|
|
155
155
|
if (m !== -1) {
|
|
156
|
-
if (
|
|
157
|
-
for (;r <
|
|
156
|
+
if (p = t.slice(a + 1, m), r = C, t.charCodeAt(r) === 35)
|
|
157
|
+
for (;r < o && !q(t.charCodeAt(r)); )
|
|
158
158
|
r++;
|
|
159
159
|
y = true;
|
|
160
160
|
}
|
|
@@ -162,9 +162,9 @@ var require_dist = __commonJS(function(exports, module) {
|
|
|
162
162
|
if (!y) {
|
|
163
163
|
let v = t.indexOf(`
|
|
164
164
|
`, c);
|
|
165
|
-
v === -1 && (v =
|
|
165
|
+
v === -1 && (v = o);
|
|
166
166
|
let u;
|
|
167
|
-
if (
|
|
167
|
+
if (o < 4096)
|
|
168
168
|
u = t.indexOf("#", c), (u === -1 || u > v) && (u = v);
|
|
169
169
|
else
|
|
170
170
|
for (u = c;u < v && t.charCodeAt(u) !== 35; )
|
|
@@ -174,38 +174,41 @@ var require_dist = __commonJS(function(exports, module) {
|
|
|
174
174
|
m++;
|
|
175
175
|
for (;C > m && w(t.charCodeAt(C - 1)); )
|
|
176
176
|
C--;
|
|
177
|
-
let
|
|
178
|
-
if (C - m >= 2 && (
|
|
179
|
-
for (;r <
|
|
177
|
+
let O = t.charCodeAt(m);
|
|
178
|
+
if (p = t.slice(m, C), p.includes("\u2028") || p.includes("\u2029") ? p = p.replace(/^(['"`])([\s\S]*)\1$/mg, "$2") : C - m >= 2 && (O === 39 || O === 34 || O === 96) && t.charCodeAt(C - 1) === O && (p = t.slice(m + 1, C - 1)), r = u, u < v)
|
|
179
|
+
for (;r < o && !q(t.charCodeAt(r)); )
|
|
180
180
|
r++;
|
|
181
181
|
}
|
|
182
|
-
g === 34 && (y || a < r) &&
|
|
183
|
-
`).replace(/\\r/g, "\r")),
|
|
182
|
+
g === 34 && (y || a < r) && p.indexOf("\\") !== -1 && (p = p.replace(/\\n/g, `
|
|
183
|
+
`).replace(/\\r/g, "\r")), n[h] = p;
|
|
184
184
|
}
|
|
185
|
-
return
|
|
185
|
+
return n;
|
|
186
186
|
}
|
|
187
|
-
function
|
|
188
|
-
return
|
|
187
|
+
function se(e, n) {
|
|
188
|
+
return n && $(n.fast) ? oe(e) : ne(e);
|
|
189
189
|
}
|
|
190
190
|
function T(e) {
|
|
191
191
|
console.log(`\u2506 ${e}`);
|
|
192
192
|
}
|
|
193
|
-
function
|
|
193
|
+
function ie(e) {
|
|
194
194
|
console.error(`\u25C7 ${e}`);
|
|
195
195
|
}
|
|
196
196
|
function V(e) {
|
|
197
|
-
return e[0] === "~" ?
|
|
197
|
+
return e[0] === "~" ? I.join(Z.homedir(), e.slice(1)) : e;
|
|
198
198
|
}
|
|
199
|
-
function
|
|
200
|
-
|
|
199
|
+
function ce(e = {}) {
|
|
200
|
+
let n = { ...e };
|
|
201
|
+
for (let t of Object.keys(n))
|
|
202
|
+
n[t] === undefined && delete n[t];
|
|
203
|
+
return { ...B(), ...n };
|
|
201
204
|
}
|
|
202
|
-
function
|
|
203
|
-
e =
|
|
204
|
-
let
|
|
205
|
-
e && e.processEnv != null && (
|
|
205
|
+
function ae(e) {
|
|
206
|
+
e = ce(e);
|
|
207
|
+
let n = I.resolve(process.cwd(), ".env"), t = "utf8", o = process.env;
|
|
208
|
+
e && e.processEnv != null && (o = e.processEnv);
|
|
206
209
|
let r = $(e && e.debug);
|
|
207
210
|
e && e.encoding ? t = e.encoding : r && T("no encoding is specified (UTF-8 is used by default)");
|
|
208
|
-
let s = [
|
|
211
|
+
let s = [n];
|
|
209
212
|
if (e && e.path)
|
|
210
213
|
if (!Array.isArray(e.path))
|
|
211
214
|
s = [V(e.path)];
|
|
@@ -217,116 +220,116 @@ var require_dist = __commonJS(function(exports, module) {
|
|
|
217
220
|
let i, l = {}, d = { fast: e.fast };
|
|
218
221
|
for (let c of s)
|
|
219
222
|
try {
|
|
220
|
-
let a = A.parse(
|
|
223
|
+
let a = A.parse(z.readFileSync(c, { encoding: t }), d);
|
|
221
224
|
A.populate(l, a, e);
|
|
222
225
|
} catch (a) {
|
|
223
226
|
r && T(`failed to load ${c} ${a.message}`), i = a;
|
|
224
227
|
}
|
|
225
|
-
let
|
|
228
|
+
let h = A.populate(o, l, e), f = $(Object.prototype.hasOwnProperty.call(e, "quiet") ? e.quiet : B(o).quiet);
|
|
226
229
|
if (r || !f) {
|
|
227
|
-
let c = Object.keys(
|
|
230
|
+
let c = Object.keys(h).length, a = [];
|
|
228
231
|
for (let g of s)
|
|
229
232
|
try {
|
|
230
|
-
let
|
|
231
|
-
a.push(
|
|
232
|
-
} catch (
|
|
233
|
-
r && T(`failed to load ${g} ${
|
|
233
|
+
let p = I.relative(process.cwd(), g instanceof ee ? te(g) : g);
|
|
234
|
+
a.push(p);
|
|
235
|
+
} catch (p) {
|
|
236
|
+
r && T(`failed to load ${g} ${p.message}`), i = p;
|
|
234
237
|
}
|
|
235
|
-
|
|
238
|
+
ie(`injected env (${c}) from ${a.join(",")}`);
|
|
236
239
|
}
|
|
237
240
|
return i ? { parsed: l, error: i } : { parsed: l };
|
|
238
241
|
}
|
|
239
|
-
function
|
|
242
|
+
function le(e) {
|
|
240
243
|
return A.configDotenv(e);
|
|
241
244
|
}
|
|
242
|
-
function
|
|
243
|
-
let
|
|
244
|
-
if (e === null || typeof e != "object" ||
|
|
245
|
+
function fe(e, n, t = {}) {
|
|
246
|
+
let o = $(t && t.debug), r = $(t && t.override), s = {};
|
|
247
|
+
if (e === null || typeof e != "object" || n === null || typeof n != "object") {
|
|
245
248
|
let i = new Error("OBJECT_REQUIRED: Please check the processEnv argument being passed to populate");
|
|
246
249
|
throw i.code = "OBJECT_REQUIRED", i;
|
|
247
250
|
}
|
|
248
|
-
for (let i of Object.keys(
|
|
249
|
-
Object.prototype.hasOwnProperty.call(e, i) ? (r === true && (e[i] =
|
|
251
|
+
for (let i of Object.keys(n))
|
|
252
|
+
Object.prototype.hasOwnProperty.call(e, i) ? (r === true && (e[i] = n[i], s[i] = n[i]), o && T(r === true ? `"${i}" is already defined and WAS overwritten` : `"${i}" is already defined and was NOT overwritten`)) : (e[i] = n[i], s[i] = n[i]);
|
|
250
253
|
return s;
|
|
251
254
|
}
|
|
252
|
-
var A = { configDotenv:
|
|
255
|
+
var A = { configDotenv: ae, config: le, parse: se, populate: fe };
|
|
253
256
|
x.exports.configDotenv = A.configDotenv;
|
|
254
257
|
x.exports.config = A.config;
|
|
255
258
|
x.exports.parse = A.parse;
|
|
256
259
|
x.exports.populate = A.populate;
|
|
257
260
|
x.exports = A;
|
|
258
261
|
});
|
|
259
|
-
var M =
|
|
260
|
-
var _ = __require("child_process"),
|
|
261
|
-
function
|
|
262
|
-
let
|
|
263
|
-
for (let
|
|
264
|
-
if (
|
|
262
|
+
var M = j((Te, W) => {
|
|
263
|
+
var _ = __require("child_process"), ue = __require("fs"), L = __require("path");
|
|
264
|
+
function de(e) {
|
|
265
|
+
let n = ['"'], t = 0;
|
|
266
|
+
for (let o of e) {
|
|
267
|
+
if (o === "\\") {
|
|
265
268
|
t++;
|
|
266
269
|
continue;
|
|
267
270
|
}
|
|
268
|
-
|
|
271
|
+
o === '"' ? n.push("\\".repeat(t * 2 + 1), '"') : n.push("\\".repeat(t), o), t = 0;
|
|
269
272
|
}
|
|
270
|
-
return
|
|
273
|
+
return n.push("\\".repeat(t * 2), '"'), n.join("");
|
|
271
274
|
}
|
|
272
|
-
function H(e,
|
|
273
|
-
for (let t = 0;t <
|
|
274
|
-
let
|
|
275
|
+
function H(e, n = 1) {
|
|
276
|
+
for (let t = 0;t < n; t++) {
|
|
277
|
+
let o = [];
|
|
275
278
|
for (let r of e) {
|
|
276
279
|
let s = r.charCodeAt(0), i = s >= 48 && s <= 57 || s >= 65 && s <= 90 || s >= 97 && s <= 122, l = "\\/:._-".includes(r);
|
|
277
|
-
!i && !l && s < 128 &&
|
|
280
|
+
!i && !l && s < 128 && o.push("^"), o.push(r);
|
|
278
281
|
}
|
|
279
|
-
e =
|
|
282
|
+
e = o.join("");
|
|
280
283
|
}
|
|
281
284
|
return e;
|
|
282
285
|
}
|
|
283
|
-
function P(e,
|
|
284
|
-
let t = Object.keys(e).reverse().find((
|
|
286
|
+
function P(e, n) {
|
|
287
|
+
let t = Object.keys(e).reverse().find((o) => o.toUpperCase() === n);
|
|
285
288
|
return t === undefined ? undefined : e[t];
|
|
286
289
|
}
|
|
287
|
-
function
|
|
288
|
-
let
|
|
290
|
+
function pe(e, n, t) {
|
|
291
|
+
let o = (P(n, "PATHEXT") || ".COM;.EXE;.BAT;.CMD").split(";").filter(Boolean), s = o.some((l) => e.toLowerCase().endsWith(l.toLowerCase())) ? ["", ...o] : [...o, ""], i = /[\\/]/.test(e) ? [t] : [t, ...(P(n, "PATH") || "").split(";")];
|
|
289
292
|
for (let l of i)
|
|
290
293
|
for (let d of s) {
|
|
291
|
-
let
|
|
294
|
+
let h = L.resolve(t, l.replace(/^"|"$/g, ""), e + d);
|
|
292
295
|
try {
|
|
293
|
-
if (
|
|
294
|
-
return
|
|
296
|
+
if (ue.statSync(h).isFile())
|
|
297
|
+
return h;
|
|
295
298
|
} catch {}
|
|
296
299
|
}
|
|
297
300
|
}
|
|
298
|
-
function
|
|
301
|
+
function he(e, n, t) {
|
|
299
302
|
if (process.platform !== "win32")
|
|
300
|
-
return _.spawn(e,
|
|
301
|
-
let
|
|
303
|
+
return _.spawn(e, n, t);
|
|
304
|
+
let o = t.env || process.env, r = pe(e, o, t.cwd || process.cwd());
|
|
302
305
|
if (r && /\.(?:exe|com)$/i.test(r))
|
|
303
|
-
return _.spawn(r,
|
|
306
|
+
return _.spawn(r, n, t);
|
|
304
307
|
let s = /\.(?:bat|cmd)$/i.test(r || e), i = [H(L.normalize(r || e))];
|
|
305
|
-
for (let d of
|
|
306
|
-
i.push(H(
|
|
308
|
+
for (let d of n)
|
|
309
|
+
i.push(H(de(d), s ? 2 : 1));
|
|
307
310
|
let l = i.join(" ");
|
|
308
|
-
return _.spawn(P(
|
|
311
|
+
return _.spawn(P(o, "COMSPEC") || "cmd.exe", ["/d", "/v:off", "/s", "/c", `"${l}"`], { ...t, windowsVerbatimArguments: true });
|
|
309
312
|
}
|
|
310
|
-
W.exports =
|
|
313
|
+
W.exports = he;
|
|
311
314
|
});
|
|
312
|
-
var
|
|
313
|
-
var
|
|
315
|
+
var X = j(($e, F) => {
|
|
316
|
+
var ge = __require("fs"), me = __require("os"), Q = __require("path"), ve = __require("child_process"), Ce = M(), R = N(), { optionsFromEnv: J } = k();
|
|
314
317
|
function D() {
|
|
315
318
|
console.log(["Usage: dotenv run [--help] [-q|--quiet] [--debug] [--override] [--fast] [-f|--file <paths>] [--] <command> [args...]", "", "Run a command with environment variables from a .env file.", "Place dotenv options before the command; all following arguments go to the command.", "", "Options:", " -f, --file <paths> .env paths, comma-separated or repeated (default: .env)", " -q, --quiet suppress the injected env message", " --debug enable debug logging", " --override override existing environment variables", " --fast use the faster character-scanner parser", "", "Environment variables (DOTENV_CONFIG_* names remain as fallbacks):", " DOTENV_PATH, DOTENV_ENCODING, DOTENV_QUIET,", " DOTENV_DEBUG, DOTENV_OVERRIDE,", " DOTENV_FAST"].join(`
|
|
316
319
|
`));
|
|
317
320
|
}
|
|
318
321
|
function we(e) {
|
|
319
|
-
let
|
|
320
|
-
for (let
|
|
321
|
-
let f = e[
|
|
322
|
+
let n = [], t = false, o, r, s, i, l = -1;
|
|
323
|
+
for (let h = 0;h < e.length; h++) {
|
|
324
|
+
let f = e[h];
|
|
322
325
|
if (f === "--") {
|
|
323
|
-
l =
|
|
326
|
+
l = h + 1;
|
|
324
327
|
break;
|
|
325
328
|
}
|
|
326
329
|
if (f === "--help" || f === "-h")
|
|
327
330
|
return { help: true };
|
|
328
331
|
if (f === "--quiet" || f === "-q") {
|
|
329
|
-
|
|
332
|
+
o = true;
|
|
330
333
|
continue;
|
|
331
334
|
}
|
|
332
335
|
if (f === "--debug") {
|
|
@@ -342,51 +345,51 @@ var require_dist = __commonJS(function(exports, module) {
|
|
|
342
345
|
continue;
|
|
343
346
|
}
|
|
344
347
|
if (f === "-f" || f === "--file" || f.startsWith("-f=") || f.startsWith("--file=")) {
|
|
345
|
-
let c = f.indexOf("="), a = c === -1 ? f : f.slice(0, c), g = c === -1 ? e[++
|
|
348
|
+
let c = f.indexOf("="), a = c === -1 ? f : f.slice(0, c), g = c === -1 ? e[++h] : f.slice(c + 1);
|
|
346
349
|
if (!g || g === "--")
|
|
347
350
|
return { error: `${a} requires a path` };
|
|
348
|
-
let
|
|
349
|
-
if (
|
|
351
|
+
let p = g.split(",").map((y) => y.trim()).filter(Boolean);
|
|
352
|
+
if (p.length === 0)
|
|
350
353
|
return { error: `${a} requires a path` };
|
|
351
|
-
|
|
354
|
+
n.push(...p), t = true;
|
|
352
355
|
continue;
|
|
353
356
|
}
|
|
354
357
|
if (f.startsWith("-"))
|
|
355
358
|
return { error: `unknown option: ${f}` };
|
|
356
|
-
l =
|
|
359
|
+
l = h;
|
|
357
360
|
break;
|
|
358
361
|
}
|
|
359
362
|
let d = l === -1 ? [] : e.slice(l);
|
|
360
|
-
return { paths:
|
|
363
|
+
return { paths: n, pathSet: t, quiet: o, debug: r, override: s, fast: i, command: d };
|
|
361
364
|
}
|
|
362
365
|
function Ae(e) {
|
|
363
|
-
return e[0] === "~" ? Q.join(
|
|
366
|
+
return e[0] === "~" ? Q.join(me.homedir(), e.slice(1)) : e;
|
|
364
367
|
}
|
|
365
368
|
function Ee(e) {
|
|
366
|
-
let
|
|
367
|
-
return
|
|
369
|
+
let n = J(), t = { encoding: n.encoding || "utf8", quiet: n.quiet, debug: n.debug === true, override: n.override === true, fast: n.fast === true, paths: [".env"], defaultPath: true };
|
|
370
|
+
return n.path != null && (t.paths = [n.path], t.defaultPath = false), e.pathSet && (t.paths = e.paths, t.defaultPath = false), e.quiet != null && (t.quiet = e.quiet), e.debug != null && (t.debug = e.debug), e.override != null && (t.override = e.override), e.fast != null && (t.fast = e.fast), t;
|
|
368
371
|
}
|
|
369
372
|
function be(e) {
|
|
370
|
-
let
|
|
373
|
+
let n = {}, t = [], o = { override: e.override, debug: e.debug };
|
|
371
374
|
for (let s of e.paths) {
|
|
372
375
|
let i = Q.resolve(process.cwd(), Ae(s));
|
|
373
376
|
try {
|
|
374
|
-
let l = R.parse(
|
|
375
|
-
R.populate(
|
|
377
|
+
let l = R.parse(ge.readFileSync(i, { encoding: e.encoding }), { fast: e.fast });
|
|
378
|
+
R.populate(n, l, o), t.push(s);
|
|
376
379
|
} catch (l) {
|
|
377
380
|
if (e.debug && console.log(`\u2506 failed to load ${s} ${l.message}`), !(e.defaultPath && l.code === "ENOENT"))
|
|
378
381
|
throw l;
|
|
379
382
|
}
|
|
380
383
|
}
|
|
381
|
-
return { injected: R.populate(process.env,
|
|
384
|
+
return { injected: R.populate(process.env, n, o), loadedPaths: t };
|
|
382
385
|
}
|
|
383
|
-
function
|
|
384
|
-
let
|
|
385
|
-
if (
|
|
386
|
+
function K(e) {
|
|
387
|
+
let n = e[0];
|
|
388
|
+
if (n === "--help" || n === "-h") {
|
|
386
389
|
D();
|
|
387
390
|
return;
|
|
388
391
|
}
|
|
389
|
-
if (
|
|
392
|
+
if (n !== "run") {
|
|
390
393
|
D(), process.exitCode = 1;
|
|
391
394
|
return;
|
|
392
395
|
}
|
|
@@ -403,22 +406,22 @@ var require_dist = __commonJS(function(exports, module) {
|
|
|
403
406
|
D(), process.exitCode = 1;
|
|
404
407
|
return;
|
|
405
408
|
}
|
|
406
|
-
let
|
|
409
|
+
let o = Ee(t);
|
|
407
410
|
try {
|
|
408
|
-
let c = be(
|
|
409
|
-
if (!
|
|
410
|
-
let
|
|
411
|
-
c.loadedPaths.length > 0 && (
|
|
411
|
+
let c = be(o);
|
|
412
|
+
if (!(o.quiet == null ? J().quiet : o.quiet)) {
|
|
413
|
+
let g = `\u25C7 injected env (${Object.keys(c.injected).length})`;
|
|
414
|
+
c.loadedPaths.length > 0 && (g += ` from ${c.loadedPaths.join(", ")}`), console.error(g);
|
|
412
415
|
}
|
|
413
416
|
} catch (c) {
|
|
414
417
|
console.error(`dotenv: ${c.message}`), process.exitCode = 1;
|
|
415
418
|
return;
|
|
416
419
|
}
|
|
417
|
-
let r = !!process.stdin.isTTY, s = process.platform !== "win32" && !r, i =
|
|
418
|
-
function
|
|
420
|
+
let r = !!process.stdin.isTTY, s = process.platform !== "win32" && !r, i = Ce(t.command[0], t.command.slice(1), { stdio: "inherit", detached: s }), l = new Map, d = 0;
|
|
421
|
+
function h(c) {
|
|
419
422
|
if (!(!i.pid || i.exitCode !== null || i.signalCode !== null)) {
|
|
420
423
|
if (process.platform === "win32") {
|
|
421
|
-
|
|
424
|
+
ve.spawnSync("taskkill", ["/pid", String(i.pid), "/T", "/F"], { stdio: "ignore" });
|
|
422
425
|
return;
|
|
423
426
|
}
|
|
424
427
|
try {
|
|
@@ -439,11 +442,11 @@ var require_dist = __commonJS(function(exports, module) {
|
|
|
439
442
|
if (d++, r && process.platform !== "win32" && d === 1)
|
|
440
443
|
return;
|
|
441
444
|
if (d > 1) {
|
|
442
|
-
|
|
445
|
+
h(d === 2 ? "SIGTERM" : "SIGKILL");
|
|
443
446
|
return;
|
|
444
447
|
}
|
|
445
448
|
}
|
|
446
|
-
|
|
449
|
+
h(c);
|
|
447
450
|
};
|
|
448
451
|
l.set(c, a), process.on(c, a);
|
|
449
452
|
}
|
|
@@ -453,16 +456,16 @@ var require_dist = __commonJS(function(exports, module) {
|
|
|
453
456
|
f(), typeof c == "number" ? process.exit(c) : (setInterval(() => {}, 1000), process.kill(process.pid, a));
|
|
454
457
|
});
|
|
455
458
|
}
|
|
456
|
-
F.exports =
|
|
457
|
-
F === __require.main &&
|
|
459
|
+
F.exports = K;
|
|
460
|
+
F === __require.main && K(process.argv.slice(2));
|
|
458
461
|
});
|
|
459
|
-
var
|
|
460
|
-
var
|
|
461
|
-
module.exports =
|
|
462
|
-
module.exports.config =
|
|
463
|
-
module.exports.configDotenv =
|
|
464
|
-
module.exports.parse =
|
|
465
|
-
module.exports.populate =
|
|
462
|
+
var S = N();
|
|
463
|
+
var qe = X();
|
|
464
|
+
module.exports = S;
|
|
465
|
+
module.exports.config = S.config;
|
|
466
|
+
module.exports.configDotenv = S.configDotenv;
|
|
467
|
+
module.exports.parse = S.parse;
|
|
468
|
+
module.exports.populate = S.populate;
|
|
466
469
|
});
|
|
467
470
|
|
|
468
471
|
// src/load-env.ts
|
|
@@ -509,7 +512,7 @@ var createPkcePair = () => {
|
|
|
509
512
|
verifier
|
|
510
513
|
};
|
|
511
514
|
};
|
|
512
|
-
// ../../../node_modules/.bun/zod@4.6.
|
|
515
|
+
// ../../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/core/util.js
|
|
513
516
|
function getEnumValues(entries) {
|
|
514
517
|
const numericValues = Object.values(entries).filter((v) => typeof v === "number");
|
|
515
518
|
const values = Object.entries(entries).filter(([k, _]) => numericValues.indexOf(+k) === -1).map(([_, v]) => v);
|
|
@@ -855,6 +858,18 @@ function prefixIssues(path, issues) {
|
|
|
855
858
|
function unwrapMessage(message) {
|
|
856
859
|
return typeof message === "string" ? message : message?.message;
|
|
857
860
|
}
|
|
861
|
+
function sizeCaps(defChecks) {
|
|
862
|
+
const caps = [];
|
|
863
|
+
for (const ch of defChecks ?? []) {
|
|
864
|
+
const d = ch._zod.def;
|
|
865
|
+
if (!/_(length|size)$|_equals$/.test(d.check))
|
|
866
|
+
break;
|
|
867
|
+
const max = d.maximum ?? d.length ?? d.size;
|
|
868
|
+
if (max >= 0)
|
|
869
|
+
caps.push([max, ch]);
|
|
870
|
+
}
|
|
871
|
+
return caps;
|
|
872
|
+
}
|
|
858
873
|
function attachSchema(issues, start, inst) {
|
|
859
874
|
var _a;
|
|
860
875
|
for (let i = start;i < issues.length; i++) {
|
|
@@ -1052,7 +1067,7 @@ function constantCatch(value) {
|
|
|
1052
1067
|
return fn;
|
|
1053
1068
|
}
|
|
1054
1069
|
|
|
1055
|
-
// ../../../node_modules/.bun/zod@4.6.
|
|
1070
|
+
// ../../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/core/core.js
|
|
1056
1071
|
var _a;
|
|
1057
1072
|
var _zodDesc = { value: undefined, enumerable: false };
|
|
1058
1073
|
var _E = "captureStackTrace" in Error ? Error : null;
|
|
@@ -1170,7 +1185,7 @@ function config2(newConfig) {
|
|
|
1170
1185
|
Object.assign(globalConfig, newConfig);
|
|
1171
1186
|
return globalConfig;
|
|
1172
1187
|
}
|
|
1173
|
-
// ../../../node_modules/.bun/zod@4.6.
|
|
1188
|
+
// ../../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/core/errors.js
|
|
1174
1189
|
function _getMessage() {
|
|
1175
1190
|
const internals = this._zod;
|
|
1176
1191
|
internals.message ?? (internals.message = JSON.stringify(internals.def, jsonStringifyReplacer, 2));
|
|
@@ -1285,7 +1300,7 @@ function formatError(error, mapper = (issue) => issue.message) {
|
|
|
1285
1300
|
return fieldErrors;
|
|
1286
1301
|
}
|
|
1287
1302
|
|
|
1288
|
-
// ../../../node_modules/.bun/zod@4.6.
|
|
1303
|
+
// ../../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/core/parse.js
|
|
1289
1304
|
function finalizeParams(callee, params) {
|
|
1290
1305
|
return { callee: params?.callee ?? callee, Err: params?.Err };
|
|
1291
1306
|
}
|
|
@@ -1432,7 +1447,7 @@ var _safeEncodeAsync = (_Err) => async (schema, value, _ctx) => {
|
|
|
1432
1447
|
var _safeDecodeAsync = (_Err) => async (schema, value, _ctx) => {
|
|
1433
1448
|
return _safeParseAsync(_Err)(schema, value, _ctx);
|
|
1434
1449
|
};
|
|
1435
|
-
// ../../../node_modules/.bun/zod@4.6.
|
|
1450
|
+
// ../../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/core/regexes.js
|
|
1436
1451
|
var cuid = /^[cC][0-9a-z]{6,}$/;
|
|
1437
1452
|
var cuid2 = /^[0-9a-z]+$/;
|
|
1438
1453
|
var ulid = /^[0-7][0-9A-HJKMNP-TV-Za-hjkmnp-tv-z]{25}$/;
|
|
@@ -1490,7 +1505,7 @@ var _null = /^null$/i;
|
|
|
1490
1505
|
var lowercase = /^[^A-Z]*$/;
|
|
1491
1506
|
var uppercase = /^[^a-z]*$/;
|
|
1492
1507
|
|
|
1493
|
-
// ../../../node_modules/.bun/zod@4.6.
|
|
1508
|
+
// ../../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/core/checks.js
|
|
1494
1509
|
var $ZodCheck = /* @__PURE__ */ $constructor("$ZodCheck", (inst, def) => {
|
|
1495
1510
|
var _a;
|
|
1496
1511
|
inst._zod ?? (inst._zod = {});
|
|
@@ -1806,7 +1821,7 @@ var $ZodCheckOverwrite = /* @__PURE__ */ $constructor("$ZodCheckOverwrite", (ins
|
|
|
1806
1821
|
};
|
|
1807
1822
|
});
|
|
1808
1823
|
|
|
1809
|
-
// ../../../node_modules/.bun/zod@4.6.
|
|
1824
|
+
// ../../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/core/doc.js
|
|
1810
1825
|
class Doc {
|
|
1811
1826
|
constructor(args = [], closed = {}) {
|
|
1812
1827
|
this.content = [];
|
|
@@ -1848,14 +1863,14 @@ ${content.join(`
|
|
|
1848
1863
|
}
|
|
1849
1864
|
}
|
|
1850
1865
|
|
|
1851
|
-
// ../../../node_modules/.bun/zod@4.6.
|
|
1866
|
+
// ../../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/core/versions.js
|
|
1852
1867
|
var version = {
|
|
1853
1868
|
major: 4,
|
|
1854
1869
|
minor: 6,
|
|
1855
|
-
patch:
|
|
1870
|
+
patch: 7
|
|
1856
1871
|
};
|
|
1857
1872
|
|
|
1858
|
-
// ../../../node_modules/.bun/zod@4.6.
|
|
1873
|
+
// ../../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/core/schemas.js
|
|
1859
1874
|
var $ZodType = /* @__PURE__ */ $constructor("$ZodType", (inst, def) => {
|
|
1860
1875
|
var _a;
|
|
1861
1876
|
inst ?? (inst = {});
|
|
@@ -2421,6 +2436,29 @@ var $ZodNever = /* @__PURE__ */ $constructor("$ZodNever", (inst, def) => {
|
|
|
2421
2436
|
return payload;
|
|
2422
2437
|
};
|
|
2423
2438
|
});
|
|
2439
|
+
function capSize(inst, size) {
|
|
2440
|
+
const caps = sizeCaps(inst._zod.def.checks);
|
|
2441
|
+
if (!caps.length)
|
|
2442
|
+
return;
|
|
2443
|
+
const cap = Math.min(...caps.map((c) => c[0]));
|
|
2444
|
+
const parse = inst._zod.parse;
|
|
2445
|
+
inst._zod.parse = (payload, ctx) => {
|
|
2446
|
+
const n = size(payload.value);
|
|
2447
|
+
if (n > cap && !ctx?.skipChecks && ctx?.direction !== "backward") {
|
|
2448
|
+
for (const [max, ch] of sizeCaps(inst._zod.def.checks)) {
|
|
2449
|
+
if (n > max && ch._zod.def.when(payload)) {
|
|
2450
|
+
const start = payload.issues.length;
|
|
2451
|
+
ch._zod.check(payload);
|
|
2452
|
+
payload.issues[start].continue = false;
|
|
2453
|
+
attachSchema(payload.issues, start, inst);
|
|
2454
|
+
return payload;
|
|
2455
|
+
}
|
|
2456
|
+
}
|
|
2457
|
+
}
|
|
2458
|
+
return parse(payload, ctx);
|
|
2459
|
+
};
|
|
2460
|
+
}
|
|
2461
|
+
var arraySize = (input) => Array.isArray(input) ? input.length : -1;
|
|
2424
2462
|
function handleArrayResult(result, final, index) {
|
|
2425
2463
|
if (result.issues.length) {
|
|
2426
2464
|
final.issues.push(...prefixIssues(index, result.issues));
|
|
@@ -2464,6 +2502,7 @@ var $ZodArray = /* @__PURE__ */ $constructor("$ZodArray", (inst, def) => {
|
|
|
2464
2502
|
}
|
|
2465
2503
|
return payload;
|
|
2466
2504
|
};
|
|
2505
|
+
capSize(inst, arraySize);
|
|
2467
2506
|
});
|
|
2468
2507
|
function handlePropertyResult(result, final, key, input, optin, optout) {
|
|
2469
2508
|
const isPresent = key in input;
|
|
@@ -3246,7 +3285,7 @@ function handleRefineResult(result, payload, input, inst) {
|
|
|
3246
3285
|
payload.issues.push(issue(_iss));
|
|
3247
3286
|
}
|
|
3248
3287
|
}
|
|
3249
|
-
// ../../../node_modules/.bun/zod@4.6.
|
|
3288
|
+
// ../../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/core/memoizer.js
|
|
3250
3289
|
class $ZodCyclicError extends Error {
|
|
3251
3290
|
constructor() {
|
|
3252
3291
|
super(`Cannot parse a reference cycle that closes through a transform`);
|
|
@@ -3515,7 +3554,7 @@ function isBackEdge(ctx, value) {
|
|
|
3515
3554
|
const backEdges = ctx[STATE]?.backEdges;
|
|
3516
3555
|
return backEdges !== undefined && isRef(value) && backEdges.has(value);
|
|
3517
3556
|
}
|
|
3518
|
-
// ../../../node_modules/.bun/zod@4.6.
|
|
3557
|
+
// ../../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/locales/en.js
|
|
3519
3558
|
var error = () => {
|
|
3520
3559
|
const Sizable = {
|
|
3521
3560
|
string: { unit: "characters", verb: "to have" },
|
|
@@ -3637,7 +3676,7 @@ function en_default() {
|
|
|
3637
3676
|
localeError: error()
|
|
3638
3677
|
};
|
|
3639
3678
|
}
|
|
3640
|
-
// ../../../node_modules/.bun/zod@4.6.
|
|
3679
|
+
// ../../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/core/registries.js
|
|
3641
3680
|
var _a2;
|
|
3642
3681
|
class $ZodRegistry {
|
|
3643
3682
|
constructor() {
|
|
@@ -3684,7 +3723,7 @@ function registry() {
|
|
|
3684
3723
|
}
|
|
3685
3724
|
(_a2 = globalThis).__zod_globalRegistry ?? (_a2.__zod_globalRegistry = registry());
|
|
3686
3725
|
var globalRegistry = globalThis.__zod_globalRegistry;
|
|
3687
|
-
// ../../../node_modules/.bun/zod@4.6.
|
|
3726
|
+
// ../../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/core/api.js
|
|
3688
3727
|
function snapshotChecks(def) {
|
|
3689
3728
|
if (def.checks)
|
|
3690
3729
|
def.checks = [...def.checks];
|
|
@@ -4138,7 +4177,7 @@ function _check(fn, params) {
|
|
|
4138
4177
|
ch._zod.check = fn;
|
|
4139
4178
|
return ch;
|
|
4140
4179
|
}
|
|
4141
|
-
// ../../../node_modules/.bun/zod@4.6.
|
|
4180
|
+
// ../../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/core/to-json-schema.js
|
|
4142
4181
|
function assignProps(target, ...sources) {
|
|
4143
4182
|
for (const source of sources) {
|
|
4144
4183
|
for (const key of Reflect.ownKeys(source)) {
|
|
@@ -4661,7 +4700,7 @@ var createStandardJSONSchemaMethod = (schema, io, processors = {}) => (params) =
|
|
|
4661
4700
|
extractDefs(ctx, schema);
|
|
4662
4701
|
return finalize(ctx, schema);
|
|
4663
4702
|
};
|
|
4664
|
-
// ../../../node_modules/.bun/zod@4.6.
|
|
4703
|
+
// ../../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/core/json-schema-processors.js
|
|
4665
4704
|
var narrowMin = (agg, key, value) => {
|
|
4666
4705
|
if (agg[key] === undefined || value > agg[key])
|
|
4667
4706
|
agg[key] = value;
|
|
@@ -5090,7 +5129,7 @@ var optionalProcessor = (schema, ctx, _json, params) => {
|
|
|
5090
5129
|
const seen = ctx.seen.get(schema);
|
|
5091
5130
|
seen.ref = def.innerType;
|
|
5092
5131
|
};
|
|
5093
|
-
// ../../../node_modules/.bun/zod@4.6.
|
|
5132
|
+
// ../../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/classic/errors.js
|
|
5094
5133
|
var _installedErrorProtos = /* @__PURE__ */ new WeakSet([Object.prototype, Error.prototype]);
|
|
5095
5134
|
function _lazyMethod(proto, key, make) {
|
|
5096
5135
|
Object.defineProperty(proto, key, {
|
|
@@ -5135,7 +5174,7 @@ var ZodRealError = /* @__PURE__ */ $constructor("ZodError", initializer2, undefi
|
|
|
5135
5174
|
Parent: Error
|
|
5136
5175
|
});
|
|
5137
5176
|
|
|
5138
|
-
// ../../../node_modules/.bun/zod@4.6.
|
|
5177
|
+
// ../../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/classic/parse.js
|
|
5139
5178
|
var parse2 = /* @__PURE__ */ _parse(ZodRealError);
|
|
5140
5179
|
var parseAsync = /* @__PURE__ */ _parseAsync(ZodRealError);
|
|
5141
5180
|
var safeParse = /* @__PURE__ */ _safeParse(ZodRealError);
|
|
@@ -5149,7 +5188,7 @@ var safeDecode = /* @__PURE__ */ _safeDecode(ZodRealError);
|
|
|
5149
5188
|
var safeEncodeAsync = /* @__PURE__ */ _safeEncodeAsync(ZodRealError);
|
|
5150
5189
|
var safeDecodeAsync = /* @__PURE__ */ _safeDecodeAsync(ZodRealError);
|
|
5151
5190
|
|
|
5152
|
-
// ../../../node_modules/.bun/zod@4.6.
|
|
5191
|
+
// ../../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/classic/schemas.js
|
|
5153
5192
|
function _ensureDefaultLocale() {
|
|
5154
5193
|
if (!globalConfig.localeError)
|
|
5155
5194
|
config2(en_default());
|
|
@@ -6716,6 +6755,155 @@ var logoutCliSession = async ({
|
|
|
6716
6755
|
// src/cli.ts
|
|
6717
6756
|
import { readFileSync } from "fs";
|
|
6718
6757
|
|
|
6758
|
+
// ../utils/src/data-table-sort-keys.ts
|
|
6759
|
+
var INVENTORY_SORT_IDS = [
|
|
6760
|
+
"itemCategory",
|
|
6761
|
+
"category",
|
|
6762
|
+
"supplier",
|
|
6763
|
+
"cost",
|
|
6764
|
+
"name",
|
|
6765
|
+
"createdAt",
|
|
6766
|
+
"updatedAt"
|
|
6767
|
+
];
|
|
6768
|
+
var ITEM_CATEGORY_SORT_IDS = [
|
|
6769
|
+
"name",
|
|
6770
|
+
"itemCount",
|
|
6771
|
+
"createdAt",
|
|
6772
|
+
"createdBy"
|
|
6773
|
+
];
|
|
6774
|
+
|
|
6775
|
+
// ../db/src/generated/prisma/enums.ts
|
|
6776
|
+
var EstimationMode = {
|
|
6777
|
+
MICRO: "MICRO",
|
|
6778
|
+
MANPOWER_SPECIFIED: "MANPOWER_SPECIFIED"
|
|
6779
|
+
};
|
|
6780
|
+
var ProjectStatus = {
|
|
6781
|
+
PITCH: "PITCH",
|
|
6782
|
+
WON: "WON",
|
|
6783
|
+
COMPLETED: "COMPLETED",
|
|
6784
|
+
RECONCILED: "RECONCILED",
|
|
6785
|
+
LOST: "LOST"
|
|
6786
|
+
};
|
|
6787
|
+
var BudgetStatus = {
|
|
6788
|
+
DRAFT: "DRAFT",
|
|
6789
|
+
PENDING_APPROVAL: "PENDING_APPROVAL",
|
|
6790
|
+
APPROVED: "APPROVED",
|
|
6791
|
+
REJECTED: "REJECTED",
|
|
6792
|
+
ESTIMATE_CREATED: "ESTIMATE_CREATED",
|
|
6793
|
+
ESTIMATE_SENT: "ESTIMATE_SENT",
|
|
6794
|
+
ESTIMATE_ACCEPTED: "ESTIMATE_ACCEPTED",
|
|
6795
|
+
ESTIMATE_REJECTED: "ESTIMATE_REJECTED",
|
|
6796
|
+
ESTIMATE_CLOSED: "ESTIMATE_CLOSED"
|
|
6797
|
+
};
|
|
6798
|
+
var ApprovalStatus = {
|
|
6799
|
+
PENDING_APPROVAL: "PENDING_APPROVAL",
|
|
6800
|
+
APPROVED: "APPROVED",
|
|
6801
|
+
REJECTED: "REJECTED",
|
|
6802
|
+
SUPERSEDED: "SUPERSEDED"
|
|
6803
|
+
};
|
|
6804
|
+
var ApprovalType = {
|
|
6805
|
+
BUDGET: "BUDGET",
|
|
6806
|
+
SUPPLIER: "SUPPLIER",
|
|
6807
|
+
BILL: "BILL",
|
|
6808
|
+
CUSTOMER_INVOICE: "CUSTOMER_INVOICE",
|
|
6809
|
+
QUOTATION: "QUOTATION"
|
|
6810
|
+
};
|
|
6811
|
+
var ErrorSeverity = {
|
|
6812
|
+
LOW: "LOW",
|
|
6813
|
+
MEDIUM: "MEDIUM",
|
|
6814
|
+
HIGH: "HIGH",
|
|
6815
|
+
CRITICAL: "CRITICAL"
|
|
6816
|
+
};
|
|
6817
|
+
var ErrorStatus = {
|
|
6818
|
+
UNRESOLVED: "UNRESOLVED",
|
|
6819
|
+
INVESTIGATING: "INVESTIGATING",
|
|
6820
|
+
RESOLVED: "RESOLVED",
|
|
6821
|
+
IGNORED: "IGNORED"
|
|
6822
|
+
};
|
|
6823
|
+
var CustomerInvoiceBatchStatus = {
|
|
6824
|
+
CREATING: "CREATING",
|
|
6825
|
+
PENDING_APPROVAL: "PENDING_APPROVAL",
|
|
6826
|
+
APPROVED: "APPROVED",
|
|
6827
|
+
REJECTED_VOIDED: "REJECTED_VOIDED",
|
|
6828
|
+
EXPIRED_VOIDED: "EXPIRED_VOIDED",
|
|
6829
|
+
PARTIAL_QBO_FAILURE: "PARTIAL_QBO_FAILURE"
|
|
6830
|
+
};
|
|
6831
|
+
var CustomerInvoiceStatus = {
|
|
6832
|
+
CREATED_IN_QBO: "CREATED_IN_QBO",
|
|
6833
|
+
APPROVED: "APPROVED",
|
|
6834
|
+
SENT: "SENT",
|
|
6835
|
+
PAID: "PAID",
|
|
6836
|
+
VOIDED: "VOIDED",
|
|
6837
|
+
QBO_SYNC_ERROR: "QBO_SYNC_ERROR"
|
|
6838
|
+
};
|
|
6839
|
+
var BillStatus = {
|
|
6840
|
+
DRAFT: "DRAFT",
|
|
6841
|
+
PENDING_APPROVAL: "PENDING_APPROVAL",
|
|
6842
|
+
CHECKED: "CHECKED",
|
|
6843
|
+
APPROVED: "APPROVED",
|
|
6844
|
+
PAID: "PAID",
|
|
6845
|
+
REJECTED: "REJECTED"
|
|
6846
|
+
};
|
|
6847
|
+
|
|
6848
|
+
// ../utils/src/filter-enums.ts
|
|
6849
|
+
var ExtendedApprovalStatus = {
|
|
6850
|
+
...ApprovalStatus,
|
|
6851
|
+
ALL: "ALL"
|
|
6852
|
+
};
|
|
6853
|
+
var ExtendedApprovalType = {
|
|
6854
|
+
...ApprovalType,
|
|
6855
|
+
ALL: "ALL"
|
|
6856
|
+
};
|
|
6857
|
+
var ExtendedProjectStatus = {
|
|
6858
|
+
...ProjectStatus,
|
|
6859
|
+
ALL: "ALL"
|
|
6860
|
+
};
|
|
6861
|
+
var ExtendedBudgetStatus = {
|
|
6862
|
+
...BudgetStatus,
|
|
6863
|
+
ALL: "ALL"
|
|
6864
|
+
};
|
|
6865
|
+
var ExtendedBillStatus = {
|
|
6866
|
+
...BillStatus,
|
|
6867
|
+
ALL: "ALL"
|
|
6868
|
+
};
|
|
6869
|
+
var ExtendedEstimationMode = {
|
|
6870
|
+
...EstimationMode,
|
|
6871
|
+
ALL: "ALL"
|
|
6872
|
+
};
|
|
6873
|
+
var BudgetRole = {
|
|
6874
|
+
ALL: "ALL",
|
|
6875
|
+
BD: "BD",
|
|
6876
|
+
CREATOR: "CREATOR",
|
|
6877
|
+
INSIDE_SALES: "INSIDE_SALES"
|
|
6878
|
+
};
|
|
6879
|
+
var Deals = {
|
|
6880
|
+
ALL: "ALL",
|
|
6881
|
+
SUCCESSFUL: "SUCCESSFUL",
|
|
6882
|
+
LOST: "LOST"
|
|
6883
|
+
};
|
|
6884
|
+
var TimeFrame = {
|
|
6885
|
+
ALL: "ALL",
|
|
6886
|
+
LAST_YEAR: "LAST_YEAR",
|
|
6887
|
+
LAST_6_MONTHS: "LAST_6_MONTHS",
|
|
6888
|
+
LAST_3_MONTHS: "LAST_3_MONTHS",
|
|
6889
|
+
CUSTOM: "CUSTOM"
|
|
6890
|
+
};
|
|
6891
|
+
var ChartTimeFrame = {
|
|
6892
|
+
LAST_30_DAYS: "last_30_days",
|
|
6893
|
+
LAST_3_MONTHS: "last_3_months",
|
|
6894
|
+
LAST_6_MONTHS: "last_6_months",
|
|
6895
|
+
LAST_1_YEAR: "last_1_year",
|
|
6896
|
+
ALL_TIME: "all_time"
|
|
6897
|
+
};
|
|
6898
|
+
var ExtendedErrorSeverity = {
|
|
6899
|
+
ALL: "ALL",
|
|
6900
|
+
...ErrorSeverity
|
|
6901
|
+
};
|
|
6902
|
+
var ExtendedErrorStatus = {
|
|
6903
|
+
ALL: "ALL",
|
|
6904
|
+
...ErrorStatus
|
|
6905
|
+
};
|
|
6906
|
+
|
|
6719
6907
|
// src/cli-trace.ts
|
|
6720
6908
|
var cliQuietSession = false;
|
|
6721
6909
|
var setCliQuiet = (quiet) => {
|
|
@@ -6737,6 +6925,7 @@ var SENSITIVE_FLAG = new Set([
|
|
|
6737
6925
|
"authorization"
|
|
6738
6926
|
]);
|
|
6739
6927
|
var SENSITIVE_TRACE_FIELD = new Set([
|
|
6928
|
+
"secret",
|
|
6740
6929
|
"paymentproof",
|
|
6741
6930
|
"paymentproofattachments",
|
|
6742
6931
|
"paymentproofpath",
|
|
@@ -6754,6 +6943,14 @@ var sanitizeValueForTrace = (value, seen = new WeakSet) => {
|
|
|
6754
6943
|
if (Array.isArray(value)) {
|
|
6755
6944
|
return value.map((item) => sanitizeValueForTrace(item, seen));
|
|
6756
6945
|
}
|
|
6946
|
+
if (value instanceof Error) {
|
|
6947
|
+
return sanitizeValueForTrace({
|
|
6948
|
+
...value,
|
|
6949
|
+
name: value.name,
|
|
6950
|
+
message: value.message,
|
|
6951
|
+
stack: value.stack
|
|
6952
|
+
}, seen);
|
|
6953
|
+
}
|
|
6757
6954
|
const prototype = Object.getPrototypeOf(value);
|
|
6758
6955
|
if (prototype !== Object.prototype && prototype !== null)
|
|
6759
6956
|
return value;
|
|
@@ -6776,9 +6973,8 @@ var sanitizeFlagsForTrace = (flags) => {
|
|
|
6776
6973
|
};
|
|
6777
6974
|
var consumeCliQuietFlags = (flags) => {
|
|
6778
6975
|
const fromEnv = process.env.BB_CLI_QUIET === "1";
|
|
6779
|
-
const fromFlags = flags.quiet === true
|
|
6976
|
+
const fromFlags = flags.quiet === true;
|
|
6780
6977
|
delete flags.quiet;
|
|
6781
|
-
delete flags.q;
|
|
6782
6978
|
return fromEnv || fromFlags;
|
|
6783
6979
|
};
|
|
6784
6980
|
var logCliAction = (record) => {
|
|
@@ -6864,7 +7060,7 @@ var api2 = new Proxy({}, {
|
|
|
6864
7060
|
});
|
|
6865
7061
|
|
|
6866
7062
|
// src/prisma-enums.ts
|
|
6867
|
-
var
|
|
7063
|
+
var ProjectStatus2 = {
|
|
6868
7064
|
PITCH: "PITCH",
|
|
6869
7065
|
WON: "WON",
|
|
6870
7066
|
COMPLETED: "COMPLETED",
|
|
@@ -6878,7 +7074,7 @@ var SupplierQuotationStatus = {
|
|
|
6878
7074
|
REJECTED: "REJECTED",
|
|
6879
7075
|
SUPERSEDED: "SUPERSEDED"
|
|
6880
7076
|
};
|
|
6881
|
-
var
|
|
7077
|
+
var BudgetStatus2 = {
|
|
6882
7078
|
DRAFT: "DRAFT",
|
|
6883
7079
|
PENDING_APPROVAL: "PENDING_APPROVAL",
|
|
6884
7080
|
APPROVED: "APPROVED",
|
|
@@ -6889,13 +7085,13 @@ var BudgetStatus = {
|
|
|
6889
7085
|
ESTIMATE_REJECTED: "ESTIMATE_REJECTED",
|
|
6890
7086
|
ESTIMATE_CLOSED: "ESTIMATE_CLOSED"
|
|
6891
7087
|
};
|
|
6892
|
-
var
|
|
7088
|
+
var ApprovalStatus2 = {
|
|
6893
7089
|
PENDING_APPROVAL: "PENDING_APPROVAL",
|
|
6894
7090
|
APPROVED: "APPROVED",
|
|
6895
7091
|
REJECTED: "REJECTED",
|
|
6896
7092
|
SUPERSEDED: "SUPERSEDED"
|
|
6897
7093
|
};
|
|
6898
|
-
var
|
|
7094
|
+
var ApprovalType2 = {
|
|
6899
7095
|
BUDGET: "BUDGET",
|
|
6900
7096
|
SUPPLIER: "SUPPLIER",
|
|
6901
7097
|
BILL: "BILL",
|
|
@@ -6909,7 +7105,7 @@ var UserRole = {
|
|
|
6909
7105
|
INSIDE_SALES: "INSIDE_SALES",
|
|
6910
7106
|
ACCOUNTING_TEAM: "ACCOUNTING_TEAM"
|
|
6911
7107
|
};
|
|
6912
|
-
var
|
|
7108
|
+
var BillStatus2 = {
|
|
6913
7109
|
DRAFT: "DRAFT",
|
|
6914
7110
|
PENDING_APPROVAL: "PENDING_APPROVAL",
|
|
6915
7111
|
CHECKED: "CHECKED",
|
|
@@ -6950,212 +7146,87 @@ import { readFile as readFile2, writeFile } from "fs/promises";
|
|
|
6950
7146
|
import { basename } from "path";
|
|
6951
7147
|
import { createInterface as createInterface2 } from "readline/promises";
|
|
6952
7148
|
|
|
6953
|
-
//
|
|
6954
|
-
var
|
|
6955
|
-
|
|
6956
|
-
|
|
6957
|
-
|
|
6958
|
-
|
|
6959
|
-
|
|
6960
|
-
|
|
6961
|
-
|
|
6962
|
-
|
|
6963
|
-
|
|
7149
|
+
// src/runtime/error.ts
|
|
7150
|
+
var invocationErrorCodes = new Set([
|
|
7151
|
+
"USAGE",
|
|
7152
|
+
"VALIDATION",
|
|
7153
|
+
"CONFIRMATION_REQUIRED"
|
|
7154
|
+
]);
|
|
7155
|
+
var trpcCodeMap = {
|
|
7156
|
+
BAD_REQUEST: "VALIDATION",
|
|
7157
|
+
CONFLICT: "CONFLICT",
|
|
7158
|
+
FORBIDDEN: "AUTHORIZATION",
|
|
7159
|
+
INTERNAL_SERVER_ERROR: "API",
|
|
7160
|
+
METHOD_NOT_SUPPORTED: "API",
|
|
7161
|
+
NOT_FOUND: "NOT_FOUND",
|
|
7162
|
+
PARSE_ERROR: "VALIDATION",
|
|
7163
|
+
PAYLOAD_TOO_LARGE: "VALIDATION",
|
|
7164
|
+
PRECONDITION_FAILED: "CONFLICT",
|
|
7165
|
+
TIMEOUT: "NETWORK",
|
|
7166
|
+
TOO_MANY_REQUESTS: "API",
|
|
7167
|
+
UNAUTHORIZED: "AUTHENTICATION",
|
|
7168
|
+
UNPROCESSABLE_CONTENT: "VALIDATION"
|
|
6964
7169
|
};
|
|
6965
|
-
var
|
|
6966
|
-
|
|
6967
|
-
|
|
6968
|
-
|
|
6969
|
-
|
|
6970
|
-
|
|
6971
|
-
|
|
6972
|
-
|
|
6973
|
-
|
|
6974
|
-
|
|
6975
|
-
|
|
6976
|
-
|
|
6977
|
-
|
|
6978
|
-
|
|
6979
|
-
|
|
6980
|
-
|
|
6981
|
-
|
|
6982
|
-
|
|
6983
|
-
|
|
6984
|
-
|
|
6985
|
-
|
|
6986
|
-
|
|
6987
|
-
|
|
6988
|
-
|
|
6989
|
-
|
|
6990
|
-
|
|
6991
|
-
|
|
6992
|
-
|
|
6993
|
-
|
|
6994
|
-
|
|
6995
|
-
|
|
6996
|
-
|
|
6997
|
-
|
|
6998
|
-
|
|
6999
|
-
|
|
7000
|
-
|
|
7001
|
-
|
|
7002
|
-
|
|
7003
|
-
|
|
7004
|
-
|
|
7005
|
-
|
|
7006
|
-
|
|
7007
|
-
|
|
7008
|
-
}
|
|
7009
|
-
|
|
7010
|
-
|
|
7011
|
-
|
|
7012
|
-
|
|
7013
|
-
|
|
7014
|
-
|
|
7015
|
-
|
|
7016
|
-
|
|
7017
|
-
|
|
7018
|
-
|
|
7019
|
-
|
|
7020
|
-
|
|
7021
|
-
|
|
7022
|
-
|
|
7023
|
-
|
|
7024
|
-
|
|
7025
|
-
|
|
7026
|
-
// ../utils/src/filter-enums.ts
|
|
7027
|
-
var ExtendedApprovalStatus = {
|
|
7028
|
-
...ApprovalStatus2,
|
|
7029
|
-
ALL: "ALL"
|
|
7030
|
-
};
|
|
7031
|
-
var ExtendedApprovalType = {
|
|
7032
|
-
...ApprovalType2,
|
|
7033
|
-
ALL: "ALL"
|
|
7034
|
-
};
|
|
7035
|
-
var ExtendedProjectStatus = {
|
|
7036
|
-
...ProjectStatus2,
|
|
7037
|
-
ALL: "ALL"
|
|
7038
|
-
};
|
|
7039
|
-
var ExtendedBudgetStatus = {
|
|
7040
|
-
...BudgetStatus2,
|
|
7041
|
-
ALL: "ALL"
|
|
7042
|
-
};
|
|
7043
|
-
var ExtendedBillStatus = {
|
|
7044
|
-
...BillStatus2,
|
|
7045
|
-
ALL: "ALL"
|
|
7046
|
-
};
|
|
7047
|
-
var ExtendedEstimationMode = {
|
|
7048
|
-
...EstimationMode,
|
|
7049
|
-
ALL: "ALL"
|
|
7050
|
-
};
|
|
7051
|
-
var BudgetRole = {
|
|
7052
|
-
ALL: "ALL",
|
|
7053
|
-
BD: "BD",
|
|
7054
|
-
CREATOR: "CREATOR",
|
|
7055
|
-
INSIDE_SALES: "INSIDE_SALES"
|
|
7056
|
-
};
|
|
7057
|
-
var Deals = {
|
|
7058
|
-
ALL: "ALL",
|
|
7059
|
-
SUCCESSFUL: "SUCCESSFUL",
|
|
7060
|
-
LOST: "LOST"
|
|
7061
|
-
};
|
|
7062
|
-
var TimeFrame = {
|
|
7063
|
-
ALL: "ALL",
|
|
7064
|
-
LAST_YEAR: "LAST_YEAR",
|
|
7065
|
-
LAST_6_MONTHS: "LAST_6_MONTHS",
|
|
7066
|
-
LAST_3_MONTHS: "LAST_3_MONTHS",
|
|
7067
|
-
CUSTOM: "CUSTOM"
|
|
7068
|
-
};
|
|
7069
|
-
var ExtendedErrorSeverity = {
|
|
7070
|
-
ALL: "ALL",
|
|
7071
|
-
...ErrorSeverity
|
|
7072
|
-
};
|
|
7073
|
-
var ExtendedErrorStatus = {
|
|
7074
|
-
ALL: "ALL",
|
|
7075
|
-
...ErrorStatus
|
|
7076
|
-
};
|
|
7077
|
-
|
|
7078
|
-
// src/runtime/error.ts
|
|
7079
|
-
var invocationErrorCodes = new Set([
|
|
7080
|
-
"USAGE",
|
|
7081
|
-
"VALIDATION",
|
|
7082
|
-
"CONFIRMATION_REQUIRED"
|
|
7083
|
-
]);
|
|
7084
|
-
var trpcCodeMap = {
|
|
7085
|
-
BAD_REQUEST: "VALIDATION",
|
|
7086
|
-
CONFLICT: "CONFLICT",
|
|
7087
|
-
FORBIDDEN: "AUTHORIZATION",
|
|
7088
|
-
INTERNAL_SERVER_ERROR: "API",
|
|
7089
|
-
METHOD_NOT_SUPPORTED: "API",
|
|
7090
|
-
NOT_FOUND: "NOT_FOUND",
|
|
7091
|
-
PARSE_ERROR: "VALIDATION",
|
|
7092
|
-
PAYLOAD_TOO_LARGE: "VALIDATION",
|
|
7093
|
-
PRECONDITION_FAILED: "CONFLICT",
|
|
7094
|
-
TIMEOUT: "NETWORK",
|
|
7095
|
-
TOO_MANY_REQUESTS: "API",
|
|
7096
|
-
UNAUTHORIZED: "AUTHENTICATION",
|
|
7097
|
-
UNPROCESSABLE_CONTENT: "VALIDATION"
|
|
7098
|
-
};
|
|
7099
|
-
var cliErrorCodes = new Set([
|
|
7100
|
-
"USAGE",
|
|
7101
|
-
"VALIDATION",
|
|
7102
|
-
"CONFIRMATION_REQUIRED",
|
|
7103
|
-
"AUTHENTICATION",
|
|
7104
|
-
"AUTHORIZATION",
|
|
7105
|
-
"NOT_FOUND",
|
|
7106
|
-
"CONFLICT",
|
|
7107
|
-
"API",
|
|
7108
|
-
"NETWORK",
|
|
7109
|
-
"ABORTED",
|
|
7110
|
-
"INTERRUPTED",
|
|
7111
|
-
"INTERNAL"
|
|
7112
|
-
]);
|
|
7113
|
-
|
|
7114
|
-
class CliRuntimeError extends Error {
|
|
7115
|
-
code;
|
|
7116
|
-
details;
|
|
7117
|
-
requestId;
|
|
7118
|
-
constructor(code, message, options = {}) {
|
|
7119
|
-
super(message);
|
|
7120
|
-
this.name = "CliRuntimeError";
|
|
7121
|
-
this.code = code;
|
|
7122
|
-
this.details = options.details;
|
|
7123
|
-
this.requestId = options.requestId;
|
|
7124
|
-
}
|
|
7125
|
-
}
|
|
7126
|
-
var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
7127
|
-
var asNonEmptyString = (value) => typeof value === "string" && value.trim() !== "" ? value : undefined;
|
|
7128
|
-
var formatValidationMessage = (message, data) => {
|
|
7129
|
-
const zodError = isRecord(data?.zodError) ? data.zodError : undefined;
|
|
7130
|
-
const fieldErrors = isRecord(zodError?.fieldErrors) ? zodError.fieldErrors : undefined;
|
|
7131
|
-
const fields = fieldErrors ? Object.entries(fieldErrors).flatMap(([field, errors]) => Array.isArray(errors) ? errors.filter((entry) => typeof entry === "string").map((entry) => `${field}: ${entry}`) : []) : [];
|
|
7132
|
-
const formErrors = Array.isArray(zodError?.formErrors) ? zodError.formErrors.filter((entry) => typeof entry === "string") : [];
|
|
7133
|
-
const validationIssues = [...fields, ...formErrors];
|
|
7134
|
-
if (validationIssues.length > 0)
|
|
7135
|
-
return validationIssues.join("; ");
|
|
7136
|
-
let parsed = message;
|
|
7137
|
-
for (let depth = 0;depth < 3 && typeof parsed === "string"; depth++) {
|
|
7138
|
-
try {
|
|
7139
|
-
parsed = JSON.parse(parsed);
|
|
7140
|
-
} catch {
|
|
7141
|
-
return message;
|
|
7142
|
-
}
|
|
7143
|
-
}
|
|
7144
|
-
if (!Array.isArray(parsed) || parsed.length === 0 || !parsed.every(isRecord))
|
|
7145
|
-
return message;
|
|
7146
|
-
const issues = parsed.map((issue) => {
|
|
7147
|
-
if (!Array.isArray(issue.path) || typeof issue.message !== "string" || typeof issue.code !== "string")
|
|
7148
|
-
return;
|
|
7149
|
-
const path = issue.path.filter((part) => typeof part === "string" || typeof part === "number").join(".") || "payload";
|
|
7150
|
-
if (issue.code === "invalid_type" && typeof issue.expected === "string" && issue.message.toLowerCase().includes("required")) {
|
|
7151
|
-
return `${path} must be a ${issue.expected}${path === "cost" ? ', e.g. "19"' : ""}`;
|
|
7152
|
-
}
|
|
7153
|
-
if (issue.code === "invalid_format" && issue.format === "regex" && path === "name" && String(issue.pattern ?? issue.message).includes("A-Za-z0-9,.?@&!#'~* _;+-")) {
|
|
7154
|
-
return `${path} contains characters that are not allowed. Allowed: letters, numbers, spaces and , . ? @ & ! # ' ~ * _ ; + -`;
|
|
7155
|
-
}
|
|
7156
|
-
return `${path}: ${issue.message}`;
|
|
7157
|
-
});
|
|
7158
|
-
return issues.every((issue) => issue !== undefined) ? issues.join("; ") : message;
|
|
7170
|
+
var cliErrorCodes = new Set([
|
|
7171
|
+
"USAGE",
|
|
7172
|
+
"VALIDATION",
|
|
7173
|
+
"CONFIRMATION_REQUIRED",
|
|
7174
|
+
"AUTHENTICATION",
|
|
7175
|
+
"AUTHORIZATION",
|
|
7176
|
+
"NOT_FOUND",
|
|
7177
|
+
"CONFLICT",
|
|
7178
|
+
"API",
|
|
7179
|
+
"NETWORK",
|
|
7180
|
+
"ABORTED",
|
|
7181
|
+
"INTERRUPTED",
|
|
7182
|
+
"INTERNAL"
|
|
7183
|
+
]);
|
|
7184
|
+
|
|
7185
|
+
class CliRuntimeError extends Error {
|
|
7186
|
+
code;
|
|
7187
|
+
details;
|
|
7188
|
+
requestId;
|
|
7189
|
+
constructor(code, message, options = {}) {
|
|
7190
|
+
super(message);
|
|
7191
|
+
this.name = "CliRuntimeError";
|
|
7192
|
+
this.code = code;
|
|
7193
|
+
this.details = options.details;
|
|
7194
|
+
this.requestId = options.requestId;
|
|
7195
|
+
}
|
|
7196
|
+
}
|
|
7197
|
+
var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
7198
|
+
var asNonEmptyString = (value) => typeof value === "string" && value.trim() !== "" ? value : undefined;
|
|
7199
|
+
var formatValidationMessage = (message, data) => {
|
|
7200
|
+
const zodError = isRecord(data?.zodError) ? data.zodError : undefined;
|
|
7201
|
+
const fieldErrors = isRecord(zodError?.fieldErrors) ? zodError.fieldErrors : undefined;
|
|
7202
|
+
const fields = fieldErrors ? Object.entries(fieldErrors).flatMap(([field, errors]) => Array.isArray(errors) ? errors.filter((entry) => typeof entry === "string").map((entry) => `${field}: ${entry}`) : []) : [];
|
|
7203
|
+
const formErrors = Array.isArray(zodError?.formErrors) ? zodError.formErrors.filter((entry) => typeof entry === "string") : [];
|
|
7204
|
+
const validationIssues = [...fields, ...formErrors];
|
|
7205
|
+
if (validationIssues.length > 0)
|
|
7206
|
+
return validationIssues.join("; ");
|
|
7207
|
+
let parsed = message;
|
|
7208
|
+
for (let depth = 0;depth < 3 && typeof parsed === "string"; depth++) {
|
|
7209
|
+
try {
|
|
7210
|
+
parsed = JSON.parse(parsed);
|
|
7211
|
+
} catch {
|
|
7212
|
+
return message;
|
|
7213
|
+
}
|
|
7214
|
+
}
|
|
7215
|
+
if (!Array.isArray(parsed) || parsed.length === 0 || !parsed.every(isRecord))
|
|
7216
|
+
return message;
|
|
7217
|
+
const issues = parsed.map((issue) => {
|
|
7218
|
+
if (!Array.isArray(issue.path) || typeof issue.message !== "string" || typeof issue.code !== "string")
|
|
7219
|
+
return;
|
|
7220
|
+
const path = issue.path.filter((part) => typeof part === "string" || typeof part === "number").join(".") || "payload";
|
|
7221
|
+
if (issue.code === "invalid_type" && typeof issue.expected === "string" && issue.message.toLowerCase().includes("required")) {
|
|
7222
|
+
return `${path} must be a ${issue.expected}${path === "cost" ? ', e.g. "19"' : ""}`;
|
|
7223
|
+
}
|
|
7224
|
+
if (issue.code === "invalid_format" && issue.format === "regex" && path === "name" && String(issue.pattern ?? issue.message).includes("A-Za-z0-9,.?@&!#'~* _;+-")) {
|
|
7225
|
+
return `${path} contains characters that are not allowed. Allowed: letters, numbers, spaces and , . ? @ & ! # ' ~ * _ ; + -`;
|
|
7226
|
+
}
|
|
7227
|
+
return `${path}: ${issue.message}`;
|
|
7228
|
+
});
|
|
7229
|
+
return issues.every((issue) => issue !== undefined) ? issues.join("; ") : message;
|
|
7159
7230
|
};
|
|
7160
7231
|
var asDetails = (value) => {
|
|
7161
7232
|
if (!isRecord(value))
|
|
@@ -7277,9 +7348,9 @@ var customerInvoiceLifecycleStatuses = [
|
|
|
7277
7348
|
];
|
|
7278
7349
|
|
|
7279
7350
|
// src/parse-cli-enums.ts
|
|
7280
|
-
var BUDGET_STATUS_VALUES = new Set(Object.values(
|
|
7281
|
-
var BILL_STATUS_VALUES = new Set(Object.values(
|
|
7282
|
-
var PROJECT_STATUS_VALUES = new Set(Object.values(
|
|
7351
|
+
var BUDGET_STATUS_VALUES = new Set(Object.values(BudgetStatus2));
|
|
7352
|
+
var BILL_STATUS_VALUES = new Set(Object.values(BillStatus2));
|
|
7353
|
+
var PROJECT_STATUS_VALUES = new Set(Object.values(ProjectStatus2));
|
|
7283
7354
|
var SUPPLIER_QUOTATION_STATUS_VALUES = new Set(Object.values(SupplierQuotationStatus));
|
|
7284
7355
|
var CUSTOMER_INVOICE_LIFECYCLE_STATUS_VALUES = new Set(customerInvoiceLifecycleStatuses);
|
|
7285
7356
|
var USER_ROLE_VALUES = new Set(Object.values(UserRole));
|
|
@@ -7326,7 +7397,7 @@ function parseBillStatusForUpdate(raw) {
|
|
|
7326
7397
|
if (!BILL_STATUS_VALUES.has(raw)) {
|
|
7327
7398
|
throw new Error(`Invalid bill status "${raw}". Use one of: ${[...BILL_STATUS_VALUES].join(", ")}.`);
|
|
7328
7399
|
}
|
|
7329
|
-
if (raw ===
|
|
7400
|
+
if (raw === BillStatus2.PENDING_APPROVAL) {
|
|
7330
7401
|
throw new Error("Cannot set PENDING_APPROVAL via update-bill-status. Use create-bill-approval <billId> instead.");
|
|
7331
7402
|
}
|
|
7332
7403
|
return raw;
|
|
@@ -7373,6 +7444,16 @@ var PROJECT_HUB_SORT_FIELDS = new Set([
|
|
|
7373
7444
|
"companyName",
|
|
7374
7445
|
"status"
|
|
7375
7446
|
]);
|
|
7447
|
+
function parseOptionalIsoDateFlag(raw, flagName, { endOfDay = false } = {}) {
|
|
7448
|
+
if (raw === undefined || raw === "")
|
|
7449
|
+
return;
|
|
7450
|
+
const value = /^\d{4}-\d{2}-\d{2}$/.test(raw) ? `${raw}T${endOfDay ? "23:59:59.999" : "00:00:00.000"}Z` : /T\d{2}:\d{2}(:\d{2}(\.\d+)?)?$/.test(raw) ? `${raw}Z` : raw;
|
|
7451
|
+
const parsed = new Date(value);
|
|
7452
|
+
if (Number.isNaN(parsed.getTime())) {
|
|
7453
|
+
throw new Error(`${flagName} must be an ISO date (YYYY-MM-DD) or ISO datetime.`);
|
|
7454
|
+
}
|
|
7455
|
+
return parsed;
|
|
7456
|
+
}
|
|
7376
7457
|
function parseOptionalProjectHubSortBy(raw) {
|
|
7377
7458
|
if (raw === undefined || raw === "")
|
|
7378
7459
|
return;
|
|
@@ -7565,10 +7646,10 @@ function parseApprovalTypeFlag(raw) {
|
|
|
7565
7646
|
}
|
|
7566
7647
|
return u;
|
|
7567
7648
|
}
|
|
7568
|
-
var budgetStatusesForHelp = Object.values(
|
|
7569
|
-
var billStatusesForHelp = Object.values(
|
|
7570
|
-
var billStatusesForUpdateHelp = Object.values(
|
|
7571
|
-
var projectStatusesForHelp = Object.values(
|
|
7649
|
+
var budgetStatusesForHelp = Object.values(BudgetStatus2);
|
|
7650
|
+
var billStatusesForHelp = Object.values(BillStatus2);
|
|
7651
|
+
var billStatusesForUpdateHelp = Object.values(BillStatus2).filter((s) => s !== BillStatus2.PENDING_APPROVAL);
|
|
7652
|
+
var projectStatusesForHelp = Object.values(ProjectStatus2);
|
|
7572
7653
|
var userRolesForHelp = Object.values(UserRole);
|
|
7573
7654
|
|
|
7574
7655
|
// ../utils/src/rich-text.ts
|
|
@@ -8494,11 +8575,11 @@ var confirmCurrentCommand = async (input) => {
|
|
|
8494
8575
|
};
|
|
8495
8576
|
// src/commands/index.ts
|
|
8496
8577
|
import { contentType } from "mime-types";
|
|
8497
|
-
var BUDGET =
|
|
8498
|
-
var BILL =
|
|
8499
|
-
var SUPPLIER =
|
|
8500
|
-
var QUOTATION =
|
|
8501
|
-
var CUSTOMER_INVOICE =
|
|
8578
|
+
var BUDGET = ApprovalType2.BUDGET;
|
|
8579
|
+
var BILL = ApprovalType2.BILL;
|
|
8580
|
+
var SUPPLIER = ApprovalType2.SUPPLIER;
|
|
8581
|
+
var QUOTATION = ApprovalType2.QUOTATION;
|
|
8582
|
+
var CUSTOMER_INVOICE = ApprovalType2.CUSTOMER_INVOICE;
|
|
8502
8583
|
var ASANA_WON_LOST_SECTION_GIDS = new Set([
|
|
8503
8584
|
"1211678338364908",
|
|
8504
8585
|
"1211678338364907"
|
|
@@ -8555,7 +8636,7 @@ var createApprovalEmailDeliveryFailure = (error) => ({
|
|
|
8555
8636
|
error
|
|
8556
8637
|
});
|
|
8557
8638
|
function isPendingRequest(n) {
|
|
8558
|
-
return n.notificationType === "request" && n.status ===
|
|
8639
|
+
return n.notificationType === "request" && n.status === ApprovalStatus2.PENDING_APPROVAL;
|
|
8559
8640
|
}
|
|
8560
8641
|
var out = (data) => {
|
|
8561
8642
|
emitCommandResult(data);
|
|
@@ -8762,11 +8843,11 @@ var quotationAttachmentContentTypeForFileName = (fileName) => {
|
|
|
8762
8843
|
throw new Error(`Unsupported quotation attachment type: ${fileName}. Use PDF, JPEG, or PNG.`);
|
|
8763
8844
|
};
|
|
8764
8845
|
var LOCKED_BUDGET_STATUSES_REQUIRING_CONFIRMATION = new Set([
|
|
8765
|
-
|
|
8766
|
-
|
|
8767
|
-
|
|
8768
|
-
|
|
8769
|
-
|
|
8846
|
+
BudgetStatus2.ESTIMATE_CREATED,
|
|
8847
|
+
BudgetStatus2.ESTIMATE_SENT,
|
|
8848
|
+
BudgetStatus2.ESTIMATE_ACCEPTED,
|
|
8849
|
+
BudgetStatus2.ESTIMATE_REJECTED,
|
|
8850
|
+
BudgetStatus2.ESTIMATE_CLOSED
|
|
8770
8851
|
]);
|
|
8771
8852
|
var lockedBudgetStatusLabels = {
|
|
8772
8853
|
ESTIMATE_CREATED: "Estimate Created",
|
|
@@ -8888,36 +8969,20 @@ var updateProjectWithEstimateInvalidationConfirmation = async (input) => {
|
|
|
8888
8969
|
});
|
|
8889
8970
|
}
|
|
8890
8971
|
};
|
|
8891
|
-
async
|
|
8892
|
-
|
|
8893
|
-
|
|
8894
|
-
|
|
8895
|
-
|
|
8896
|
-
|
|
8897
|
-
dateFrom: opts.dateFrom,
|
|
8898
|
-
dateTo: opts.dateTo,
|
|
8899
|
-
active: opts.active,
|
|
8900
|
-
sortBy: opts.sortBy,
|
|
8901
|
-
sortDir: opts.sortDir,
|
|
8902
|
-
page: opts.page ?? 1,
|
|
8903
|
-
perPage: opts.perPage ?? 20,
|
|
8904
|
-
includeDetails: opts.includeDetails ?? true
|
|
8905
|
-
};
|
|
8906
|
-
const result = await api2.budget.getAllBudgets.query(input);
|
|
8907
|
-
out(result);
|
|
8908
|
-
}
|
|
8972
|
+
var listBudgets = async (input) => {
|
|
8973
|
+
out(await api2.budget.getAllBudgets.query(input));
|
|
8974
|
+
};
|
|
8975
|
+
var countBudgets = async (input) => {
|
|
8976
|
+
out(await api2.budget.getCounts.query(input));
|
|
8977
|
+
};
|
|
8909
8978
|
async function getBudget(id, opts) {
|
|
8910
|
-
const
|
|
8911
|
-
|
|
8912
|
-
|
|
8913
|
-
|
|
8914
|
-
})
|
|
8915
|
-
api2.budget.getBudgetItems.query({
|
|
8916
|
-
budgetId: id,
|
|
8917
|
-
includeInactive: opts?.includeInactive ?? false
|
|
8918
|
-
})
|
|
8979
|
+
const includeInactive = opts?.includeInactive ?? false;
|
|
8980
|
+
const [budget, items, totals] = await Promise.all([
|
|
8981
|
+
api2.budget.getBudget.query({ id, includeInactive }),
|
|
8982
|
+
api2.budget.getBudgetItems.query({ budgetId: id, includeInactive }),
|
|
8983
|
+
api2.budget.getBudgetItemTotals.query({ budgetId: id, includeInactive })
|
|
8919
8984
|
]);
|
|
8920
|
-
out({ budget, items });
|
|
8985
|
+
out({ budget, items: { ...items, totals } });
|
|
8921
8986
|
}
|
|
8922
8987
|
async function updateBudgetStatus(budgetId, status, opts) {
|
|
8923
8988
|
await assertSensitiveWorkflowConfirmed({
|
|
@@ -8944,7 +9009,7 @@ async function updateBudgetStatus(budgetId, status, opts) {
|
|
|
8944
9009
|
});
|
|
8945
9010
|
out({
|
|
8946
9011
|
...result,
|
|
8947
|
-
invoiceSetup: result.newStatus ===
|
|
9012
|
+
invoiceSetup: result.newStatus === BudgetStatus2.ESTIMATE_ACCEPTED && result.hasQuickbooksEstimate ? invoiceSplitSetupNextAction(budgetId) : null
|
|
8948
9013
|
});
|
|
8949
9014
|
}
|
|
8950
9015
|
var assertBudgetActionReadiness = async ({
|
|
@@ -9011,22 +9076,22 @@ var runBudgetPreflight = async (budgetId, preflight) => {
|
|
|
9011
9076
|
await updateProjectWithEstimateInvalidationConfirmation(payload);
|
|
9012
9077
|
}
|
|
9013
9078
|
};
|
|
9014
|
-
async
|
|
9015
|
-
|
|
9016
|
-
|
|
9017
|
-
|
|
9018
|
-
|
|
9019
|
-
|
|
9020
|
-
|
|
9021
|
-
|
|
9022
|
-
|
|
9023
|
-
|
|
9024
|
-
|
|
9025
|
-
|
|
9026
|
-
|
|
9027
|
-
|
|
9028
|
-
|
|
9029
|
-
}
|
|
9079
|
+
var listBills = async (input) => {
|
|
9080
|
+
out(await api2.bill.getAll.query({
|
|
9081
|
+
...input,
|
|
9082
|
+
statuses: billStatusesForApi(input.statuses),
|
|
9083
|
+
search: input.search?.trim() || undefined,
|
|
9084
|
+
createdByIds: input.createdByIds?.length ? input.createdByIds : undefined
|
|
9085
|
+
}));
|
|
9086
|
+
};
|
|
9087
|
+
var countBills = async (input) => {
|
|
9088
|
+
out(await api2.bill.getCounts.query({
|
|
9089
|
+
...input,
|
|
9090
|
+
statuses: billStatusesForApi(input.statuses),
|
|
9091
|
+
search: input.search?.trim() || undefined,
|
|
9092
|
+
createdByIds: input.createdByIds?.length ? input.createdByIds : undefined
|
|
9093
|
+
}));
|
|
9094
|
+
};
|
|
9030
9095
|
async function approveBill(billId, overBudgetOverrideReason) {
|
|
9031
9096
|
await assertSensitiveWorkflowConfirmed({
|
|
9032
9097
|
action: "Approve bill",
|
|
@@ -9041,7 +9106,7 @@ async function approveBill(billId, overBudgetOverrideReason) {
|
|
|
9041
9106
|
}
|
|
9042
9107
|
const result = await api2.bill.updateApproval.mutate({
|
|
9043
9108
|
billApprovalId: approval.id,
|
|
9044
|
-
status:
|
|
9109
|
+
status: ApprovalStatus2.APPROVED,
|
|
9045
9110
|
overBudgetOverrideReason
|
|
9046
9111
|
});
|
|
9047
9112
|
if (result.processing) {
|
|
@@ -9098,20 +9163,12 @@ async function listApprovals(opts) {
|
|
|
9098
9163
|
});
|
|
9099
9164
|
out({ items });
|
|
9100
9165
|
}
|
|
9101
|
-
async
|
|
9102
|
-
|
|
9103
|
-
|
|
9104
|
-
|
|
9105
|
-
|
|
9106
|
-
|
|
9107
|
-
createdBy: opts.createdBy,
|
|
9108
|
-
gstRegistered: opts.gstRegistered ?? null,
|
|
9109
|
-
status: opts.status,
|
|
9110
|
-
supplierTags: opts.supplierTags,
|
|
9111
|
-
active: opts.active ?? true
|
|
9112
|
-
});
|
|
9113
|
-
out(result);
|
|
9114
|
-
}
|
|
9166
|
+
var listSuppliers = async (opts) => {
|
|
9167
|
+
out(await api2.supplier.getSuppliers.query(opts));
|
|
9168
|
+
};
|
|
9169
|
+
var countSuppliers = async (opts) => {
|
|
9170
|
+
out(await api2.supplier.getSummary.query(opts));
|
|
9171
|
+
};
|
|
9115
9172
|
async function createBillApproval(billId) {
|
|
9116
9173
|
await assertSensitiveWorkflowConfirmed({
|
|
9117
9174
|
action: "Create bill approval request",
|
|
@@ -9137,10 +9194,10 @@ async function createBillApproval(billId) {
|
|
|
9137
9194
|
});
|
|
9138
9195
|
}
|
|
9139
9196
|
var validateBillStatusUpdateOptions = (opts) => {
|
|
9140
|
-
if (opts.status ===
|
|
9197
|
+
if (opts.status === BillStatus2.PAID && !opts.paymentReference?.trim()) {
|
|
9141
9198
|
throw new Error("update-bill-status requires --paymentReference when status is PAID.");
|
|
9142
9199
|
}
|
|
9143
|
-
if (opts.status !==
|
|
9200
|
+
if (opts.status !== BillStatus2.PAID && opts.paymentProofPath !== undefined) {
|
|
9144
9201
|
throw new Error("--paymentProof can only be used when status is PAID.");
|
|
9145
9202
|
}
|
|
9146
9203
|
if (opts.paymentProofPath !== undefined && !opts.paymentProofPath.trim()) {
|
|
@@ -9148,13 +9205,10 @@ var validateBillStatusUpdateOptions = (opts) => {
|
|
|
9148
9205
|
}
|
|
9149
9206
|
};
|
|
9150
9207
|
var deleteStagedPaymentProof = async (projectId, key) => {
|
|
9151
|
-
|
|
9208
|
+
await api2.attachment.deleteStagedBillAttachments.mutate({
|
|
9152
9209
|
projectId,
|
|
9153
9210
|
keys: [key]
|
|
9154
9211
|
});
|
|
9155
|
-
if (cleanup.failedKeys.includes(key)) {
|
|
9156
|
-
throw new Error(`Failed to delete staged payment proof ${key}.`);
|
|
9157
|
-
}
|
|
9158
9212
|
};
|
|
9159
9213
|
var rethrowAfterStagedPaymentProofCleanup = async (error, cleanup) => {
|
|
9160
9214
|
if (cleanup) {
|
|
@@ -9212,7 +9266,7 @@ async function updateBillStatus(opts) {
|
|
|
9212
9266
|
entity: `bill ${opts.id}`,
|
|
9213
9267
|
details: `to ${opts.status}`
|
|
9214
9268
|
});
|
|
9215
|
-
const bill = opts.paymentProofPath ? await api2.bill.
|
|
9269
|
+
const bill = opts.paymentProofPath ? await api2.bill.getPayment.query({ id: opts.id }) : null;
|
|
9216
9270
|
const paymentProof = bill && opts.paymentProofPath ? await stageBillPaymentProof(bill.projectId, opts.paymentProofPath) : undefined;
|
|
9217
9271
|
try {
|
|
9218
9272
|
const result = await api2.bill.updateStatus.mutate({
|
|
@@ -9242,7 +9296,7 @@ var recordExternalBillPayment = async (opts) => {
|
|
|
9242
9296
|
entity: `bill ${opts.id}`,
|
|
9243
9297
|
details: `already paid on ${opts.paymentDate}; reference ${opts.paymentReference}; QBO account ${opts.paymentAccount}. No money is transferred.`
|
|
9244
9298
|
});
|
|
9245
|
-
const bill = await api2.bill.
|
|
9299
|
+
const bill = await api2.bill.getPayment.query({ id: opts.id });
|
|
9246
9300
|
const proof = !bill.externalPayment && opts.paymentProofPath ? await stageBillPaymentProof(bill.projectId, opts.paymentProofPath) : undefined;
|
|
9247
9301
|
try {
|
|
9248
9302
|
out(await api2.bill.recordExternalPayment.mutate({
|
|
@@ -9254,7 +9308,7 @@ var recordExternalBillPayment = async (opts) => {
|
|
|
9254
9308
|
}));
|
|
9255
9309
|
} catch (error) {
|
|
9256
9310
|
try {
|
|
9257
|
-
const latest = await api2.bill.
|
|
9311
|
+
const latest = await api2.bill.getPayment.query({ id: opts.id });
|
|
9258
9312
|
if (latest.externalPayment?.paymentAccount === opts.paymentAccount && latest.paymentReference === opts.paymentReference.trim() && latest.paymentDate?.toISOString().slice(0, 10) === opts.paymentDate) {
|
|
9259
9313
|
out({
|
|
9260
9314
|
...latest,
|
|
@@ -9288,10 +9342,18 @@ async function patchBillInvoiceNumber(id, invoiceNumber) {
|
|
|
9288
9342
|
});
|
|
9289
9343
|
out(result);
|
|
9290
9344
|
}
|
|
9291
|
-
async
|
|
9292
|
-
|
|
9293
|
-
|
|
9294
|
-
|
|
9345
|
+
var getBillAttachments = async (input) => {
|
|
9346
|
+
out(await api2.bill.getAttachments.query(input));
|
|
9347
|
+
};
|
|
9348
|
+
var getBillApprovals = async (input) => {
|
|
9349
|
+
out(await api2.bill.getApprovals.query(input));
|
|
9350
|
+
};
|
|
9351
|
+
var getBillLineItems = async (input) => {
|
|
9352
|
+
out(await api2.bill.getLineItems.query(input));
|
|
9353
|
+
};
|
|
9354
|
+
var getBillPayment = async (id) => {
|
|
9355
|
+
out(await api2.bill.getPayment.query({ id }));
|
|
9356
|
+
};
|
|
9295
9357
|
async function stageBillAttachmentsFromPaths(projectId, filePaths) {
|
|
9296
9358
|
const attachments = [];
|
|
9297
9359
|
for (const filePath of filePaths) {
|
|
@@ -9499,7 +9561,7 @@ async function uploadBudgetWinProofFromPath(budgetId, filePath, opts) {
|
|
|
9499
9561
|
});
|
|
9500
9562
|
const result = await api2.budget.updateBudgetStatus.mutate({
|
|
9501
9563
|
id: budgetId,
|
|
9502
|
-
status:
|
|
9564
|
+
status: BudgetStatus2.ESTIMATE_ACCEPTED,
|
|
9503
9565
|
...opts?.projectManagerId !== undefined && {
|
|
9504
9566
|
projectManagerId: opts.projectManagerId
|
|
9505
9567
|
},
|
|
@@ -9523,11 +9585,12 @@ async function getBillDetails(id) {
|
|
|
9523
9585
|
out(result);
|
|
9524
9586
|
}
|
|
9525
9587
|
async function getBudgetItemsOnly(budgetId, opts) {
|
|
9526
|
-
const
|
|
9527
|
-
|
|
9528
|
-
|
|
9529
|
-
|
|
9530
|
-
|
|
9588
|
+
const includeInactive = opts?.includeInactive ?? false;
|
|
9589
|
+
const [items, totals] = await Promise.all([
|
|
9590
|
+
api2.budget.getBudgetItems.query({ budgetId, includeInactive }),
|
|
9591
|
+
api2.budget.getBudgetItemTotals.query({ budgetId, includeInactive })
|
|
9592
|
+
]);
|
|
9593
|
+
out({ ...items, totals });
|
|
9531
9594
|
}
|
|
9532
9595
|
async function addBudgetItems(opts) {
|
|
9533
9596
|
await confirmLockedBudgetChangeByBudgetId(opts.budgetId, "Add budget items");
|
|
@@ -9564,10 +9627,9 @@ var approveUnavailableItemException = async (input) => {
|
|
|
9564
9627
|
const result = await api2.budgetItem.approveUnavailableItemException.mutate(input);
|
|
9565
9628
|
out(result);
|
|
9566
9629
|
};
|
|
9567
|
-
async
|
|
9568
|
-
|
|
9569
|
-
|
|
9570
|
-
}
|
|
9630
|
+
var getBudgetCategories = async (input) => {
|
|
9631
|
+
out(await api2.budget.searchBudgetCategories.query(input));
|
|
9632
|
+
};
|
|
9571
9633
|
var getBudgetVersions = async (budgetId, options = {}) => {
|
|
9572
9634
|
if (options.all && options.cursor !== undefined) {
|
|
9573
9635
|
throw new CliRuntimeError("USAGE", "--all cannot be combined with --cursor.");
|
|
@@ -9581,15 +9643,15 @@ var getBudgetVersions = async (budgetId, options = {}) => {
|
|
|
9581
9643
|
limit: options.limit,
|
|
9582
9644
|
cursor
|
|
9583
9645
|
});
|
|
9584
|
-
versions.push(...page.
|
|
9585
|
-
cursor = page.nextCursor;
|
|
9586
|
-
if (!options.all || cursor ===
|
|
9646
|
+
versions.push(...page.items);
|
|
9647
|
+
cursor = page.pageInfo.nextCursor;
|
|
9648
|
+
if (!options.all || cursor === null)
|
|
9587
9649
|
break;
|
|
9588
9650
|
if (seenCursors.has(cursor)) {
|
|
9589
9651
|
throw new Error("Budget history pagination did not advance; export aborted.");
|
|
9590
9652
|
}
|
|
9591
9653
|
seenCursors.add(cursor);
|
|
9592
|
-
} while (cursor !==
|
|
9654
|
+
} while (cursor !== null);
|
|
9593
9655
|
out({ versions, nextCursor: cursor ?? null });
|
|
9594
9656
|
};
|
|
9595
9657
|
async function createBudgetApproval(budgetId, preflight) {
|
|
@@ -9840,14 +9902,19 @@ async function createBillFromPayload(raw, draftOnlyFlag, quotationExempt = false
|
|
|
9840
9902
|
}) : await api2.bill.create.mutate(input);
|
|
9841
9903
|
out(result);
|
|
9842
9904
|
}
|
|
9843
|
-
async
|
|
9844
|
-
|
|
9845
|
-
|
|
9846
|
-
|
|
9905
|
+
var listQuotations = async (input) => {
|
|
9906
|
+
out(await api2.quotation.listPage.query(input));
|
|
9907
|
+
};
|
|
9908
|
+
var countQuotations = async (input) => {
|
|
9909
|
+
out(await api2.quotation.getCounts.query(input));
|
|
9910
|
+
};
|
|
9847
9911
|
async function getQuotationDetails(id) {
|
|
9848
9912
|
const result = await api2.quotation.getById.query({ id });
|
|
9849
9913
|
out(result);
|
|
9850
9914
|
}
|
|
9915
|
+
var getQuotationLineItems = async (input) => {
|
|
9916
|
+
out(await api2.quotation.getLineItems.query(input));
|
|
9917
|
+
};
|
|
9851
9918
|
async function createQuotationFromPayload(raw) {
|
|
9852
9919
|
const input = parseCreateQuotationPayload(raw);
|
|
9853
9920
|
const result = await api2.quotation.createDraft.mutate(input);
|
|
@@ -9888,8 +9955,10 @@ var checkCustomerInvoiceReadiness = async (budgetId) => {
|
|
|
9888
9955
|
out(result);
|
|
9889
9956
|
};
|
|
9890
9957
|
var listCustomerInvoices = async (input) => {
|
|
9891
|
-
|
|
9892
|
-
|
|
9958
|
+
out(await api2.customerInvoice.list.query(input));
|
|
9959
|
+
};
|
|
9960
|
+
var countCustomerInvoices = async (input) => {
|
|
9961
|
+
out(await api2.customerInvoice.getCounts.query(input));
|
|
9893
9962
|
};
|
|
9894
9963
|
var listEligibleCustomerInvoiceBudgets = async (projectId) => {
|
|
9895
9964
|
const result = await api2.customerInvoice.getEligibleBudgets.query({
|
|
@@ -9914,6 +9983,18 @@ var getCustomerInvoice = async (batchId) => {
|
|
|
9914
9983
|
const result = await api2.customerInvoice.getInvoiceDetail.query({ batchId });
|
|
9915
9984
|
out(result);
|
|
9916
9985
|
};
|
|
9986
|
+
var getCustomerInvoiceInvoices = async (batchId) => {
|
|
9987
|
+
out(await api2.customerInvoice.getInvoices.query({ batchId }));
|
|
9988
|
+
};
|
|
9989
|
+
var getCustomerInvoiceLines = async (input) => {
|
|
9990
|
+
out(await api2.customerInvoice.getInvoiceLines.query(input));
|
|
9991
|
+
};
|
|
9992
|
+
var getCustomerInvoiceApprovals = async (input) => {
|
|
9993
|
+
out(await api2.customerInvoice.getApprovals.query(input));
|
|
9994
|
+
};
|
|
9995
|
+
var getCustomerInvoiceHistory = async (input) => {
|
|
9996
|
+
out(await api2.customerInvoice.getHistory.query(input));
|
|
9997
|
+
};
|
|
9917
9998
|
var getCustomerInvoiceEmailContext = async (batchId) => {
|
|
9918
9999
|
const result = await api2.customerInvoice.getInvoiceEmailContext.query({
|
|
9919
10000
|
batchId
|
|
@@ -9945,7 +10026,7 @@ var createCustomerInvoice = async (raw) => {
|
|
|
9945
10026
|
await assertSensitiveWorkflowConfirmed({
|
|
9946
10027
|
action: "Create customer invoice",
|
|
9947
10028
|
entity: `budget ${input.budgetId}`,
|
|
9948
|
-
details: `
|
|
10029
|
+
details: `queues ${input.splits.length} invoice(s) for creation in QuickBooks from the budget's remaining uninvoiced balance: ${input.splits.map((split) => `${split.label} (${split.percentage}% of the estimate), due ${new Date(split.dueDate).toISOString().slice(0, 10)}`).join("; ")}. Admin creation is auto-approved; other creators request approval. No customer email is sent.`
|
|
9949
10030
|
});
|
|
9950
10031
|
const result = await api2.customerInvoice.createInvoiceBatch.mutate(input);
|
|
9951
10032
|
out(result);
|
|
@@ -9965,7 +10046,7 @@ var deleteCustomerInvoice = async (batchId) => {
|
|
|
9965
10046
|
await assertSensitiveWorkflowConfirmed({
|
|
9966
10047
|
action: "Delete customer invoice",
|
|
9967
10048
|
entity: `invoice batch ${batchId}`,
|
|
9968
|
-
details: "
|
|
10049
|
+
details: "queues deletion of its invoices in QuickBooks; the local batch is removed once QuickBooks confirms; paid invoices are blocked until their QBO payments are reversed; removing approved coverage may reopen the estimate"
|
|
9969
10050
|
});
|
|
9970
10051
|
const result = await api2.customerInvoice.deleteInvoiceBatch.mutate({
|
|
9971
10052
|
batchId
|
|
@@ -9976,7 +10057,7 @@ var voidCustomerInvoice = async (batchId) => {
|
|
|
9976
10057
|
await assertSensitiveWorkflowConfirmed({
|
|
9977
10058
|
action: "Void customer invoice",
|
|
9978
10059
|
entity: `invoice batch ${batchId}`,
|
|
9979
|
-
details: "
|
|
10060
|
+
details: "queues a void of its invoices in QuickBooks; Budget Builder updates once QuickBooks confirms; paid invoices are blocked until their QBO payments are reversed; removing approved coverage may reopen the estimate"
|
|
9980
10061
|
});
|
|
9981
10062
|
const result = await api2.customerInvoice.voidInvoiceBatch.mutate({ batchId });
|
|
9982
10063
|
out(result);
|
|
@@ -9996,7 +10077,7 @@ var rejectCustomerInvoice = async (batchId, rejectionReason) => {
|
|
|
9996
10077
|
await assertSensitiveWorkflowConfirmed({
|
|
9997
10078
|
action: "Reject customer invoice",
|
|
9998
10079
|
entity: `invoice batch ${batchId}`,
|
|
9999
|
-
details: `
|
|
10080
|
+
details: `queues a void of its invoices in QuickBooks; once QuickBooks confirms, records the rejection reason, notifies its creator, and reopens a prematurely closed estimate when applicable`
|
|
10000
10081
|
});
|
|
10001
10082
|
const result = await api2.customerInvoice.rejectInvoiceBatch.mutate({
|
|
10002
10083
|
batchId,
|
|
@@ -10080,7 +10161,7 @@ async function createSupplierFromPayload(raw) {
|
|
|
10080
10161
|
throw new CliRuntimeError(normalized.code, `Supplier creation outcome is uncertain for ${JSON.stringify(input.name)}. Run list-suppliers and inspect matching supplier details before retrying; names may not be unique, so do not retry create-supplier until you can verify that no supplier was created. Original error: ${normalized.message}`);
|
|
10081
10162
|
}
|
|
10082
10163
|
const supplier = created.result;
|
|
10083
|
-
if (supplier.status !==
|
|
10164
|
+
if (supplier.status !== ApprovalStatus2.PENDING_APPROVAL) {
|
|
10084
10165
|
out(created);
|
|
10085
10166
|
return;
|
|
10086
10167
|
}
|
|
@@ -10147,6 +10228,10 @@ async function updateProjectFromPayload(raw) {
|
|
|
10147
10228
|
const result = await updateProjectWithEstimateInvalidationConfirmation(input);
|
|
10148
10229
|
out(result);
|
|
10149
10230
|
}
|
|
10231
|
+
var getCompanyQuickBooksSyncStatus = async (companyId) => {
|
|
10232
|
+
const result = await api2.company.getQuickBooksSyncStatus.query({ companyId });
|
|
10233
|
+
out(result);
|
|
10234
|
+
};
|
|
10150
10235
|
async function updateCompanyFromPayload(raw) {
|
|
10151
10236
|
const input = parseCompanyUpdatePayload(raw);
|
|
10152
10237
|
const result = await api2.company.updateCompany.mutate(input);
|
|
@@ -10398,16 +10483,14 @@ async function rejectQuotation(quotationId, reason) {
|
|
|
10398
10483
|
});
|
|
10399
10484
|
out(result);
|
|
10400
10485
|
}
|
|
10401
|
-
async
|
|
10402
|
-
const result = await api2.company.getCompanies.query(
|
|
10403
|
-
name: opts.name,
|
|
10404
|
-
createdBy: opts.createdBy,
|
|
10405
|
-
active: opts.active,
|
|
10406
|
-
page: opts.page ?? 1,
|
|
10407
|
-
perPage: opts.perPage ?? 20
|
|
10408
|
-
});
|
|
10486
|
+
var listCompanies = async (input) => {
|
|
10487
|
+
const result = await api2.company.getCompanies.query(input);
|
|
10409
10488
|
out(result);
|
|
10410
|
-
}
|
|
10489
|
+
};
|
|
10490
|
+
var countCompanies = async (input) => {
|
|
10491
|
+
const result = await api2.company.getCompanyCounts.query(input);
|
|
10492
|
+
out(result);
|
|
10493
|
+
};
|
|
10411
10494
|
async function getCompany(id) {
|
|
10412
10495
|
const company = await api2.company.getCompanyById.query({ id });
|
|
10413
10496
|
out(company);
|
|
@@ -10416,31 +10499,26 @@ async function createCompany(opts) {
|
|
|
10416
10499
|
const result = await api2.company.createCompany.mutate(opts);
|
|
10417
10500
|
out(result);
|
|
10418
10501
|
}
|
|
10419
|
-
var searchExistingCompanies = async (
|
|
10420
|
-
out(await api2.company.searchExistingCompanies.query(
|
|
10502
|
+
var searchExistingCompanies = async (input) => {
|
|
10503
|
+
out(await api2.company.searchExistingCompanies.query(input));
|
|
10421
10504
|
};
|
|
10422
10505
|
var reuseExistingCompany = async (input) => {
|
|
10423
10506
|
out(await api2.company.useExistingCompany.mutate(input));
|
|
10424
10507
|
};
|
|
10425
|
-
async
|
|
10426
|
-
const result = await api2.project.getAllProjects.query(
|
|
10427
|
-
companyId: opts.companyId,
|
|
10428
|
-
name: opts.name,
|
|
10429
|
-
status: opts.status,
|
|
10430
|
-
active: opts.active,
|
|
10431
|
-
page: opts.page ?? 1,
|
|
10432
|
-
perPage: opts.perPage ?? 20
|
|
10433
|
-
});
|
|
10508
|
+
var listProjects = async (input) => {
|
|
10509
|
+
const result = await api2.project.getAllProjects.query(input);
|
|
10434
10510
|
out(result);
|
|
10435
|
-
}
|
|
10436
|
-
var
|
|
10437
|
-
const result = await api2.project.
|
|
10438
|
-
...opts,
|
|
10439
|
-
page: opts.page ?? 1,
|
|
10440
|
-
perPage: opts.perPage ?? 20
|
|
10441
|
-
});
|
|
10511
|
+
};
|
|
10512
|
+
var countProjects = async (input) => {
|
|
10513
|
+
const result = await api2.project.getProjectCounts.query(input);
|
|
10442
10514
|
out(result);
|
|
10443
10515
|
};
|
|
10516
|
+
var listProjectHubs = async (input) => {
|
|
10517
|
+
out(await api2.project.getAllProjectHubs.query(input));
|
|
10518
|
+
};
|
|
10519
|
+
var countProjectHubs = async (input) => {
|
|
10520
|
+
out(await api2.project.getProjectHubCounts.query(input));
|
|
10521
|
+
};
|
|
10444
10522
|
async function getProject(id) {
|
|
10445
10523
|
const [project, budgetsOverview, billsOverview] = await Promise.all([
|
|
10446
10524
|
api2.project.getProjectDetailsById.query({ id }),
|
|
@@ -10536,7 +10614,7 @@ var reconcileProject = async (projectId) => {
|
|
|
10536
10614
|
out(result);
|
|
10537
10615
|
};
|
|
10538
10616
|
var completeProject = async (projectId) => {
|
|
10539
|
-
await updateProjectStatus(projectId,
|
|
10617
|
+
await updateProjectStatus(projectId, ProjectStatus2.COMPLETED);
|
|
10540
10618
|
};
|
|
10541
10619
|
var importQuickBooksProjectId = async (projectId, projectUrl) => {
|
|
10542
10620
|
const result = await api2.project.importQboProjectId.mutate({
|
|
@@ -10545,13 +10623,70 @@ var importQuickBooksProjectId = async (projectId, projectUrl) => {
|
|
|
10545
10623
|
});
|
|
10546
10624
|
out(result);
|
|
10547
10625
|
};
|
|
10548
|
-
var
|
|
10549
|
-
|
|
10550
|
-
out(result);
|
|
10626
|
+
var listWebhookEventTypes = async () => {
|
|
10627
|
+
out(await api2.webhook.listEventTypes.query());
|
|
10551
10628
|
};
|
|
10552
|
-
var
|
|
10553
|
-
await
|
|
10554
|
-
|
|
10629
|
+
var listWebhookEndpoints = async () => {
|
|
10630
|
+
out(await api2.webhook.listEndpoints.query());
|
|
10631
|
+
};
|
|
10632
|
+
var getWebhookEndpoint = async (id) => {
|
|
10633
|
+
out(await api2.webhook.getEndpoint.query({ id }));
|
|
10634
|
+
};
|
|
10635
|
+
var createWebhookEndpoint = async (input) => {
|
|
10636
|
+
const result = await api2.webhook.createEndpoint.mutate(input);
|
|
10637
|
+
out({
|
|
10638
|
+
...result,
|
|
10639
|
+
note: "Store the signing secret now; Budget Builder never shows it again."
|
|
10640
|
+
});
|
|
10641
|
+
};
|
|
10642
|
+
var updateWebhookEndpoint = async (input) => {
|
|
10643
|
+
out(await api2.webhook.updateEndpoint.mutate(input));
|
|
10644
|
+
};
|
|
10645
|
+
var deleteWebhookEndpoint = async (id) => {
|
|
10646
|
+
await assertSensitiveWorkflowConfirmed({
|
|
10647
|
+
action: "Delete webhook endpoint and its delivery history",
|
|
10648
|
+
entity: `webhook endpoint ${id}`
|
|
10649
|
+
});
|
|
10650
|
+
out(await api2.webhook.deleteEndpoint.mutate({ id }));
|
|
10651
|
+
};
|
|
10652
|
+
var rotateWebhookSecret = async (input) => {
|
|
10653
|
+
await assertSensitiveWorkflowConfirmed({
|
|
10654
|
+
action: "Rotate webhook signing secret",
|
|
10655
|
+
entity: `webhook endpoint ${input.id}`,
|
|
10656
|
+
details: `previous secrets keep signing for ${input.previousSecretTtlHours ?? 24}h`
|
|
10657
|
+
});
|
|
10658
|
+
const result = await api2.webhook.rotateSecret.mutate(input);
|
|
10659
|
+
out({
|
|
10660
|
+
...result,
|
|
10661
|
+
note: "Store the new signing secret now; Budget Builder never shows it again."
|
|
10662
|
+
});
|
|
10663
|
+
};
|
|
10664
|
+
var sendWebhookTestEvent = async (id) => {
|
|
10665
|
+
out(await api2.webhook.sendTestEvent.mutate({ id }));
|
|
10666
|
+
};
|
|
10667
|
+
var listWebhookDeliveries = async (input) => {
|
|
10668
|
+
out(await api2.webhook.listDeliveries.query(input));
|
|
10669
|
+
};
|
|
10670
|
+
var getWebhookDelivery = async (deliveryId) => {
|
|
10671
|
+
out(await api2.webhook.getDelivery.query({ deliveryId }));
|
|
10672
|
+
};
|
|
10673
|
+
var replayWebhookDelivery = async (deliveryId) => {
|
|
10674
|
+
out(await api2.webhook.replayDelivery.mutate({ deliveryId }));
|
|
10675
|
+
};
|
|
10676
|
+
var listIntegrationOperations = async (input) => {
|
|
10677
|
+
const result = await api2.integration.listOperations.query(input);
|
|
10678
|
+
out(result);
|
|
10679
|
+
};
|
|
10680
|
+
var getIntegrationOperation = async (operationId) => {
|
|
10681
|
+
const result = await api2.integration.getOperation.query({ operationId });
|
|
10682
|
+
out(result);
|
|
10683
|
+
};
|
|
10684
|
+
var countIntegrationOperations = async (input) => {
|
|
10685
|
+
out(await api2.integration.getCounts.query(input));
|
|
10686
|
+
};
|
|
10687
|
+
var retryIntegrationOperation = async (operationId, confirmExternalStateReconciled, outboundEmailResolution, providerMessageId) => {
|
|
10688
|
+
await assertSensitiveWorkflowConfirmed({
|
|
10689
|
+
action: outboundEmailResolution === "ACCEPTED" ? "Reconcile integration operation as completed" : "Retry integration operation (QuickBooks jobs with a saved attempt check QuickBooks first and never resend an applied change)",
|
|
10555
10690
|
entity: `operation ${operationId}`,
|
|
10556
10691
|
details: outboundEmailResolution === "ACCEPTED" ? `mark provider-accepted email sent with message ID ${providerMessageId ?? "<missing>"}` : outboundEmailResolution === "NOT_ACCEPTED_RETRY" ? "rotate the Resend idempotency key and retry provider delivery" : confirmExternalStateReconciled ? "after confirming the external state has been reconciled" : undefined
|
|
10557
10692
|
});
|
|
@@ -10563,10 +10698,25 @@ var retryIntegrationOperation = async (operationId, confirmExternalStateReconcil
|
|
|
10563
10698
|
});
|
|
10564
10699
|
out(result);
|
|
10565
10700
|
};
|
|
10701
|
+
var reconcileResourceOperation = async (operationId) => {
|
|
10702
|
+
await assertSensitiveWorkflowConfirmed({
|
|
10703
|
+
action: "Verify QuickBooks resource outcome",
|
|
10704
|
+
entity: `operation ${operationId}`,
|
|
10705
|
+
details: "verify the saved receipt or read QuickBooks when the attempt is uncertain, then queue local update/archive/reactivation finalization without repeating the provider mutation"
|
|
10706
|
+
});
|
|
10707
|
+
const result = await api2.integration.reconcileResourceOperation.mutate({
|
|
10708
|
+
operationId
|
|
10709
|
+
});
|
|
10710
|
+
out(result);
|
|
10711
|
+
};
|
|
10566
10712
|
var listInboundSources = async (input) => {
|
|
10567
10713
|
const result = await api2.inbound.listSources.query(input);
|
|
10568
10714
|
out(result);
|
|
10569
10715
|
};
|
|
10716
|
+
var countInboundSources = async (input) => {
|
|
10717
|
+
const result = await api2.inbound.countSources.query(input);
|
|
10718
|
+
out(result);
|
|
10719
|
+
};
|
|
10570
10720
|
var createInboundSource = async (input) => {
|
|
10571
10721
|
const result = await api2.inbound.createSource.mutate(input);
|
|
10572
10722
|
out(result);
|
|
@@ -10583,6 +10733,9 @@ var listInboundSubmissions = async (input) => {
|
|
|
10583
10733
|
const result = await api2.inbound.listSubmissions.query(input);
|
|
10584
10734
|
out(result);
|
|
10585
10735
|
};
|
|
10736
|
+
var countInboundSubmissions = async (input) => {
|
|
10737
|
+
out(await api2.inbound.countSubmissions.query(input));
|
|
10738
|
+
};
|
|
10586
10739
|
var getInboundSubmission = async (submissionId) => {
|
|
10587
10740
|
const result = await api2.inbound.getSubmission.query({ submissionId });
|
|
10588
10741
|
out(result);
|
|
@@ -10610,39 +10763,32 @@ async function listContacts(companyId) {
|
|
|
10610
10763
|
});
|
|
10611
10764
|
out(contacts);
|
|
10612
10765
|
}
|
|
10613
|
-
async
|
|
10614
|
-
|
|
10615
|
-
|
|
10616
|
-
|
|
10617
|
-
|
|
10618
|
-
|
|
10619
|
-
const [items, { total, counts }] = await Promise.all([
|
|
10620
|
-
api2.item.getItems.query({ ...filters, page: opts.page ?? 1, perPage }),
|
|
10621
|
-
api2.item.getItemCounts.query(filters)
|
|
10622
|
-
]);
|
|
10623
|
-
out({ items, pageCount: Math.ceil(total / perPage), counts });
|
|
10624
|
-
}
|
|
10766
|
+
var listItems = async (input) => {
|
|
10767
|
+
out(await api2.item.getItems.query(input));
|
|
10768
|
+
};
|
|
10769
|
+
var countItems = async (input) => {
|
|
10770
|
+
out(await api2.item.getItemCounts.query(input));
|
|
10771
|
+
};
|
|
10625
10772
|
async function getItem(id) {
|
|
10626
10773
|
const item = await api2.item.getItem.query({ id });
|
|
10627
10774
|
out(item);
|
|
10628
10775
|
}
|
|
10629
|
-
async
|
|
10630
|
-
const result = await api2.
|
|
10631
|
-
page: opts.page ?? 1,
|
|
10632
|
-
perPage: opts.perPage ?? 50
|
|
10633
|
-
});
|
|
10776
|
+
var getItemQuickBooksSyncStatus = async (itemId) => {
|
|
10777
|
+
const result = await api2.item.getQuickBooksSyncStatus.query({ id: itemId });
|
|
10634
10778
|
out(result);
|
|
10635
|
-
}
|
|
10636
|
-
async
|
|
10637
|
-
|
|
10638
|
-
|
|
10639
|
-
|
|
10640
|
-
|
|
10641
|
-
|
|
10642
|
-
|
|
10643
|
-
|
|
10644
|
-
|
|
10645
|
-
|
|
10779
|
+
};
|
|
10780
|
+
var listItemCategories = async (input) => {
|
|
10781
|
+
out(await api2.itemCategory.getItemCategories.query(input));
|
|
10782
|
+
};
|
|
10783
|
+
var countItemCategories = async (input) => {
|
|
10784
|
+
out(await api2.itemCategory.getCounts.query(input));
|
|
10785
|
+
};
|
|
10786
|
+
var getSupplierAnalytics = async (input) => {
|
|
10787
|
+
out(await api2.dashboard.getSupplierTableData.query(input));
|
|
10788
|
+
};
|
|
10789
|
+
var countSupplierAnalytics = async (input) => {
|
|
10790
|
+
out(await api2.dashboard.getSupplierTableCounts.query(input));
|
|
10791
|
+
};
|
|
10646
10792
|
async function createUser(input) {
|
|
10647
10793
|
const user = await api2.user.create.mutate(input);
|
|
10648
10794
|
out(user);
|
|
@@ -10659,10 +10805,12 @@ async function revokeApiKeyForUser(input) {
|
|
|
10659
10805
|
const result = await api2.mcpApiKey.revoke.mutate(input);
|
|
10660
10806
|
out(result);
|
|
10661
10807
|
}
|
|
10662
|
-
async
|
|
10663
|
-
|
|
10664
|
-
|
|
10665
|
-
|
|
10808
|
+
var listUsers = async (input) => {
|
|
10809
|
+
out(await api2.user.searchUsers.query(input));
|
|
10810
|
+
};
|
|
10811
|
+
var countUsers = async (input) => {
|
|
10812
|
+
out(await api2.user.getCounts.query(input));
|
|
10813
|
+
};
|
|
10666
10814
|
async function whoAmI() {
|
|
10667
10815
|
const user = await api2.user.getCurrentUser.query();
|
|
10668
10816
|
out(user);
|
|
@@ -10726,33 +10874,37 @@ async function getFinancialOverview(input) {
|
|
|
10726
10874
|
});
|
|
10727
10875
|
out(result);
|
|
10728
10876
|
}
|
|
10729
|
-
async
|
|
10730
|
-
|
|
10731
|
-
|
|
10732
|
-
|
|
10733
|
-
|
|
10734
|
-
|
|
10735
|
-
|
|
10736
|
-
out(
|
|
10737
|
-
}
|
|
10877
|
+
var getRecentErrors = async (input) => {
|
|
10878
|
+
out(await api2.errorLog.getRecentErrors.query(input));
|
|
10879
|
+
};
|
|
10880
|
+
var getError = async (errorId) => {
|
|
10881
|
+
out(await api2.errorLog.getErrorById.query({ errorId }));
|
|
10882
|
+
};
|
|
10883
|
+
var countErrors = async (input) => {
|
|
10884
|
+
out(await api2.errorLog.countErrors.query(input));
|
|
10885
|
+
};
|
|
10738
10886
|
async function getErrorMetrics() {
|
|
10739
10887
|
const result = await api2.errorLog.getErrorMetrics.query({});
|
|
10740
10888
|
out(result);
|
|
10741
10889
|
}
|
|
10742
10890
|
async function getApprovedBudgets(opts) {
|
|
10743
|
-
const
|
|
10744
|
-
const { budgets, totalCount } = await api2.budget.getAllBudgets.query({
|
|
10891
|
+
const filters = {
|
|
10745
10892
|
projectId: opts.projectId,
|
|
10746
10893
|
statuses: [
|
|
10747
10894
|
ExtendedBudgetStatus.APPROVED,
|
|
10748
10895
|
ExtendedBudgetStatus.ESTIMATE_ACCEPTED,
|
|
10749
10896
|
ExtendedBudgetStatus.ESTIMATE_CLOSED
|
|
10750
|
-
]
|
|
10751
|
-
|
|
10752
|
-
|
|
10753
|
-
|
|
10754
|
-
|
|
10755
|
-
|
|
10897
|
+
]
|
|
10898
|
+
};
|
|
10899
|
+
const [{ items: budgets }, { totalCount }] = await Promise.all([
|
|
10900
|
+
api2.budget.getAllBudgets.query({
|
|
10901
|
+
...filters,
|
|
10902
|
+
limit: Math.min(opts.limit ?? 50, 100),
|
|
10903
|
+
includeDetails: false
|
|
10904
|
+
}),
|
|
10905
|
+
api2.budget.getCounts.query(filters)
|
|
10906
|
+
]);
|
|
10907
|
+
const items = budgets.map((b) => {
|
|
10756
10908
|
const calc = b;
|
|
10757
10909
|
const revenue = calc.totalSellingAfterDiscount ?? 0;
|
|
10758
10910
|
const cost = calc.totalCostWithoutGst ?? 0;
|
|
@@ -10840,7 +10992,7 @@ function parseArgs(argv) {
|
|
|
10840
10992
|
}
|
|
10841
10993
|
}
|
|
10842
10994
|
} else if (arg === "-q") {
|
|
10843
|
-
flags.
|
|
10995
|
+
flags.quiet = true;
|
|
10844
10996
|
} else {
|
|
10845
10997
|
positional.push(arg);
|
|
10846
10998
|
}
|
|
@@ -10924,7 +11076,7 @@ var payloadHelp = {
|
|
|
10924
11076
|
},
|
|
10925
11077
|
"update-project": {
|
|
10926
11078
|
required: "id: string; name: string; companyId: string; contactPersonId: string; asanaTaskId: string; insideSalesId: string; businessDevelopmentId: string; venue: string; dateRange: {from: ISO date}",
|
|
10927
|
-
optional: "dateRange.to: ISO date; projectManagerId: string; pax: string; description: string; slackChannelId/slackChannelUrl/slackChannelName: strings (supply all three); requestQboAccountantNotification: boolean; confirmEstimateInvalidation: boolean",
|
|
11079
|
+
optional: "dateRange.to: ISO date; projectManagerId: string; pax: string; description: string; slackChannelId/slackChannelUrl/slackChannelName: strings (supply all three); requestQboAccountantNotification: boolean; confirmEstimateInvalidation: boolean. Changing companyId requires a contactPersonId from the new company; the company change itself does not reject existing estimates or touch existing invoices, but date, pax or venue changes in the same save still require confirmEstimateInvalidation.",
|
|
10928
11080
|
example: '{"id":"<project-id>","name":"Launch","companyId":"<company-id>","contactPersonId":"<contact-id>","asanaTaskId":"<asana-task-id>","insideSalesId":"<user-id>","businessDevelopmentId":"<user-id>","venue":"Hall","dateRange":{"from":"2026-10-01T09:00:00Z"}}'
|
|
10929
11081
|
},
|
|
10930
11082
|
"create-supplier": {
|
|
@@ -11192,6 +11344,7 @@ var financialWriteTargets = new Set([
|
|
|
11192
11344
|
]);
|
|
11193
11345
|
var deleteTargets = new Set([
|
|
11194
11346
|
"cleanup-staged-bill-attachments",
|
|
11347
|
+
"delete-webhook-endpoint",
|
|
11195
11348
|
"cleanup-staged-quotation-attachments",
|
|
11196
11349
|
"discard-customer-invoice",
|
|
11197
11350
|
"complete-project",
|
|
@@ -11200,7 +11353,14 @@ var deleteTargets = new Set([
|
|
|
11200
11353
|
"restore-budget-version",
|
|
11201
11354
|
"update-project-status"
|
|
11202
11355
|
]);
|
|
11356
|
+
var explicitEffects = {
|
|
11357
|
+
"rotate-webhook-secret": ["state-change"],
|
|
11358
|
+
"replay-webhook-delivery": ["state-change", "external-write"]
|
|
11359
|
+
};
|
|
11203
11360
|
var effectsFor = (legacyTarget) => {
|
|
11361
|
+
const explicit = explicitEffects[legacyTarget];
|
|
11362
|
+
if (explicit)
|
|
11363
|
+
return explicit;
|
|
11204
11364
|
const effects = new Set;
|
|
11205
11365
|
if (mutationPrefixes.some((prefix) => legacyTarget.startsWith(prefix))) {
|
|
11206
11366
|
effects.add("state-change");
|
|
@@ -11218,16 +11378,78 @@ var effectsFor = (legacyTarget) => {
|
|
|
11218
11378
|
};
|
|
11219
11379
|
var titleCase = (value) => value.split("-").map((word) => `${word.slice(0, 1).toUpperCase()}${word.slice(1)}`).join(" ");
|
|
11220
11380
|
var summaryFor = (legacyTarget) => {
|
|
11381
|
+
if (legacyTarget === "update-budget-status")
|
|
11382
|
+
return "Update budget status. APPROVED requires a current Lead/Admin role; budget management permission alone is insufficient. Ordinary users must request approval. Status changes invalidate old pending requests.";
|
|
11383
|
+
if (legacyTarget === "approve-budget" || legacyTarget === "reject-budget")
|
|
11384
|
+
return "Decide your assigned pending budget approval as a current Lead/Admin. Material edits supersede old requests; inspect the latest content and use a fresh request after edits.";
|
|
11385
|
+
if (legacyTarget === "create-budget-approval")
|
|
11386
|
+
return "Request budget approval for the current content, superseding older pending requests. Existing Lead/Admin autoapproval remains available.";
|
|
11387
|
+
if (legacyTarget === "update-budget-item-supplier")
|
|
11388
|
+
return "Change a budget item's eligible supplier/GST snapshot as a material financial edit. Supersede pending approvals and apply the standard budget-to-DRAFT reset policy; inspect and request approval again. An unchanged supplier is a no-op.";
|
|
11389
|
+
if (legacyTarget === "submit-quotation")
|
|
11390
|
+
return "Submit a quotation for signing and approval. Claim the captured revision and exact allocation selection; concurrent edits, budget-item deletion or restore cascades conflict instead of attaching old signed PDFs. Refresh and resubmit the current content.";
|
|
11391
|
+
if (legacyTarget === "approve-quotation")
|
|
11392
|
+
return "Approve your assigned pending quotation as a current Admin. Claim the captured revision and exact allocation selection after signing; concurrent changes conflict and roll back the decision, signed attachment and email/outbox. Refresh and review the current content before retrying.";
|
|
11221
11393
|
if (legacyTarget === "approve-supplier")
|
|
11222
11394
|
return "Approve a pending supplier request and send a requester reply email, or directly re-approve a rejected supplier as Admin/Lead without a pending request or email. QuickBooks is synchronized; archived suppliers remain archived. Argument: <supplierId>.";
|
|
11395
|
+
if (legacyTarget === "get-bill-details")
|
|
11396
|
+
return "Get a bill's summary as shown in the web app: status, amounts, people, payment and line totals. Use get-bill-line-items, get-bill-approvals, get-bill-attachments or get-bill-payment for more detail. Argument: <billId>.";
|
|
11397
|
+
if (legacyTarget === "get-bill-line-items")
|
|
11398
|
+
return "List a bill's line items with budget-item and quotation-allocation detail. <billId> [--limit 1-100] [--cursor <token>] Newest first. Returns { items, pageInfo }; follow nextCursor.";
|
|
11399
|
+
if (legacyTarget === "get-bill-approvals")
|
|
11400
|
+
return "List a bill's approval requests with approver, requester and responder. <billId> [--limit 1-50] [--cursor <token>] Newest first. Returns { items, pageInfo }; follow nextCursor.";
|
|
11401
|
+
if (legacyTarget === "get-bill-payment")
|
|
11402
|
+
return "Get a bill's payment status, reference, date, tracking URL, QuickBooks link and external payment. Argument: <billId>.";
|
|
11403
|
+
if (legacyTarget === "get-quotation")
|
|
11404
|
+
return "Get a quotation as shown in the web app: status, amounts, people, line totals, files and approvals. Use get-quotation-line-items for budget-item detail. Argument: <quotationId>.";
|
|
11405
|
+
if (legacyTarget === "get-customer-invoice")
|
|
11406
|
+
return "Get an invoice batch as shown in the web app: status, totals, people, approvals and invoice summaries. Use get-customer-invoice-invoices, get-customer-invoice-lines, get-customer-invoice-approvals or get-customer-invoice-history for more detail. Argument: <batchId>.";
|
|
11407
|
+
if (legacyTarget === "get-customer-invoice-invoices")
|
|
11408
|
+
return "List a batch's invoices with QuickBooks id/doc number, issue/due dates, amounts, sync state and sender. Argument: <batchId>.";
|
|
11409
|
+
if (legacyTarget === "get-customer-invoice-lines")
|
|
11410
|
+
return "List one invoice's lines (name, description, QuickBooks item/tax code, quantity, amounts). <invoiceId> [--limit 1-100] [--cursor <token>] Newest first. Returns { items, pageInfo }; follow nextCursor.";
|
|
11411
|
+
if (legacyTarget === "get-customer-invoice-approvals")
|
|
11412
|
+
return "List an invoice batch's approval requests with approver, requester and responder. <batchId> [--limit 1-50] [--cursor <token>] Newest first. Returns { items, pageInfo }; follow nextCursor.";
|
|
11413
|
+
if (legacyTarget === "get-customer-invoice-history")
|
|
11414
|
+
return "List an invoice batch's status history (batch/invoice status changes, source, note, actor). <batchId> [--limit 1-100] [--cursor <token>] Newest first. Returns { items, pageInfo }; follow nextCursor.";
|
|
11415
|
+
if (legacyTarget === "get-quotation-line-items")
|
|
11416
|
+
return "List a quotation's line items with budget-item, supplier and budget detail. <quotationId> [--limit 1-100] [--cursor <token>] Newest first. Returns { items, pageInfo }; follow nextCursor.";
|
|
11417
|
+
if (legacyTarget === "get-bill-attachments")
|
|
11418
|
+
return "List bill attachments with cursor pagination. <billId> [--limit 1-50] [--cursor <token>] Newest first. Returns { items, pageInfo }; follow nextCursor.";
|
|
11419
|
+
if (legacyTarget === "get-budget-categories")
|
|
11420
|
+
return "List budget categories with cursor pagination. [--q] [--limit 1-100] [--cursor <token>] Active categories, name A\u2013Z. Returns { items, pageInfo }; follow nextCursor with the same --q.";
|
|
11421
|
+
if (legacyTarget === "get-supplier-analytics")
|
|
11422
|
+
return "List supplier analytics rows with cursor pagination. [--name] [--status CSV] [--gstRegistered true|false] [--createdBy <text>] [--timeFrame ALL|LAST_YEAR|LAST_6_MONTHS|LAST_3_MONTHS|CUSTOM] [--startDate <ISO> --endDate <ISO>] [--sortBy name|gstRegistered|status|phone|email|updatedAt|createdAt] [--sortDir asc|desc] [--limit 1-100] [--cursor <token>] [--direction forward|backward] Admin. Returns { items, pageInfo }; follow nextCursor/previousCursor with the same filters and sort. --page/--perPage are rejected.";
|
|
11423
|
+
if (legacyTarget === "list-api-keys")
|
|
11424
|
+
return "List API keys with cursor pagination. [--userId <userId>] [--limit 1-100] [--cursor <token>] (newest first, { items, pageInfo }; defaults to the caller; admin required for another user)";
|
|
11425
|
+
if (legacyTarget === "list-claims")
|
|
11426
|
+
return "List reimbursable claims with cursor pagination. Same flags as list-bills (--limit 1-100, --cursor, --direction forward|backward); ignores --isClaimable. Returns { items, pageInfo }.";
|
|
11427
|
+
if (legacyTarget === "list-bills")
|
|
11428
|
+
return "List bills with cursor pagination. [--projectId] [--budgetId] [--status CSV] [--search <text>] [--isClaimable true|false] [--createdByIds <csv>] [--sortBy createdAt|amount|status] [--sortDir asc|desc] [--limit 1-100] [--cursor <token>] [--direction forward|backward] Returns { items, pageInfo }; pass nextCursor with --direction forward or previousCursor with --direction backward, keeping the same filters and sort. --page/--pageSize/--perPage are rejected.";
|
|
11429
|
+
if (legacyTarget === "list-customer-invoices")
|
|
11430
|
+
return "List customer invoice batches with cursor pagination. [budgetId] [--projectId <id>] [--companyIds CSV] [--projectIds CSV] [--budgetIds CSV] [--createdByIds CSV] [--status CSV] [--search] [--sortBy createdAt|status|totalInvoiceAmount|approvalExpiresAt] [--sortDir asc|desc] [--limit 1-100] [--cursor <token>] [--direction forward|backward] Returns { items, pageInfo }; follow nextCursor/previousCursor with the same filters and sort. --page/--perPage are rejected. No scope flag lists invoices globally. --projectId uses the project scope. A positional budgetId is a backward-compatible shortcut for --budgetIds.";
|
|
11431
|
+
if (legacyTarget === "list-quotations")
|
|
11432
|
+
return "List quotations with cursor pagination. [--projectId] [--budgetId] [--supplierId] [--status CSV] [--createdBy CSV] [--search] [--limit 1-100] [--cursor <token>] [--direction forward|backward] Newest first; returns { items, pageInfo }. Follow nextCursor/previousCursor with the same filters. --page/--pageSize/--perPage are rejected; --requesterIds remains an alias for --createdBy.";
|
|
11433
|
+
if (legacyTarget === "list-users")
|
|
11434
|
+
return "List users with cursor pagination. [--q] [--limit 1-100] [--cursor <token>] Name A\u2013Z. Returns { items, pageInfo }; follow nextCursor with the same --q. --page/--perPage are rejected.";
|
|
11435
|
+
if (legacyTarget === "list-companies")
|
|
11436
|
+
return "List companies with cursor pagination. Returns { items, pageInfo }; default sort is createdAt descending with limit 20. Pass nextCursor forward or previousCursor backward unchanged. Legacy page/perPage flags are rejected.";
|
|
11437
|
+
if (legacyTarget === "count-companies")
|
|
11438
|
+
return "Count companies independently from list pagination. Returns { totalCount, counts: { active: { true, false } } }; accepts filters only and rejects pagination/sorting flags.";
|
|
11439
|
+
if (legacyTarget === "list-projects")
|
|
11440
|
+
return "List projects with cursor pagination. Returns { items, pageInfo }; default sort is createdAt descending with limit 20. Supports legacy --status plus optional --statuses, WON-date filters (--wonFrom, --wonTo, --wonWithinDays) and --sortBy wonAt; pass nextCursor forward or previousCursor backward unchanged. Legacy page/perPage flags are rejected.";
|
|
11441
|
+
if (legacyTarget === "count-projects")
|
|
11442
|
+
return "Count projects independently from list pagination. Returns { totalCount, counts: { status, active: { true, false } } }; accepts project filters only and rejects pagination/sorting flags.";
|
|
11223
11443
|
if (legacyTarget === "search-existing-companies")
|
|
11224
|
-
return "Search BB and QuickBooks companies without writes. --query <name> [--
|
|
11444
|
+
return "Search BB and QuickBooks companies without writes. --query <name> [--limit 1-50] [--cursor <token>]. Returns { items, totalCount, pageInfo }; follow pageInfo.nextCursor with the same --query. Legacy --page is rejected.";
|
|
11225
11445
|
if (legacyTarget === "use-existing-company")
|
|
11226
11446
|
return "Reuse a company in BB and QuickBooks, creating only its missing counterpart. Supply --companyId <bbId> and/or --quickbooksId <qboId>; both explicitly connect records with different names. --website <url> fills a missing QBO import website only. --confirmDistinct true confirms no similar record represents this entity.";
|
|
11227
11447
|
if (legacyTarget === "create-company")
|
|
11228
11448
|
return "Create or reuse a company in BB and QuickBooks. --name <name> --website <url>. Similar names require --confirmDistinct true; inactive companies are never reactivated.";
|
|
11229
11449
|
if (legacyTarget === "create-project")
|
|
11230
11450
|
return "Create a project linked to an existing Asana Deals lead task. Supply --asanaTaskId in non-interactive use; interactive use searches for and selects a lead task (optionally --asanaSearch). The Slack channel is resolved from the selected Asana task unless all three Slack channel flags are supplied. For a new direct client, create the lead task using the website form first.";
|
|
11451
|
+
if (legacyTarget === "create-supplier")
|
|
11452
|
+
return "Create a supplier using --payload JSON; pending-approval suppliers also request approval and send emails. Reusing an archived name requires Admin; normal users and Leads must ask an Admin to reactivate it before editing. Recreation preserves the existing approval status and creator.";
|
|
11231
11453
|
if (legacyTarget === "preview-qbo-customer-invoice") {
|
|
11232
11454
|
return "Preview an available QuickBooks invoice selected for a BB budget using read-only QBO access. Arguments: <budgetId> <qboInvoiceId>.";
|
|
11233
11455
|
}
|
|
@@ -11243,8 +11465,22 @@ var summaryFor = (legacyTarget) => {
|
|
|
11243
11465
|
if (legacyTarget === "whoami")
|
|
11244
11466
|
return "Show the active API-key identity.";
|
|
11245
11467
|
if (legacyTarget === "list-budgets") {
|
|
11246
|
-
return "List budgets. Omit --active for active budgets only; use --active false or --active all for Admin-only historical reads.";
|
|
11247
|
-
}
|
|
11468
|
+
return "List one cursor page of budgets ({ items, pageInfo }; --limit/--cursor/--direction). Omit --active for active budgets only; use --active false or --active all for Admin-only historical reads.";
|
|
11469
|
+
}
|
|
11470
|
+
if (legacyTarget === "list-items")
|
|
11471
|
+
return "List one cursor page of catalogue items ({ items, pageInfo }; --limit/--cursor/--direction, optional --sortBy/--sortDir). --page/--perPage are rejected.";
|
|
11472
|
+
if (legacyTarget === "list-item-categories")
|
|
11473
|
+
return "List one cursor page of active item categories ({ items, pageInfo }; --limit/--cursor/--direction, optional --name/--sortBy/--sortDir). --page/--perPage are rejected.";
|
|
11474
|
+
if (legacyTarget === "count-item-categories")
|
|
11475
|
+
return "Count active item categories matching --name: { totalCount }.";
|
|
11476
|
+
if (legacyTarget === "list-integration-operations")
|
|
11477
|
+
return "List one cursor page of integration operations, newest first ({ items, pageInfo }; --limit/--cursor/--direction). --page/--perPage are rejected. Admin only.";
|
|
11478
|
+
if (legacyTarget === "count-integration-operations")
|
|
11479
|
+
return "Provider filter options for integration operations: { filterOptions }. No total; filter flags are accepted but do not change the result. Admin only.";
|
|
11480
|
+
if (legacyTarget === "count-items")
|
|
11481
|
+
return "Count catalogue items matching filters: total plus category and supplier facets (each ignores its own filter).";
|
|
11482
|
+
if (legacyTarget === "count-budgets")
|
|
11483
|
+
return "Count budgets matching filters: totalCount plus status and active facets. Omit --active for active budgets only.";
|
|
11248
11484
|
if (legacyTarget === "get-budget") {
|
|
11249
11485
|
return "Get a budget by ID. Omit --includeInactive for active budgets only; --includeInactive is an Admin-only historical read.";
|
|
11250
11486
|
}
|
|
@@ -11270,6 +11506,8 @@ var summaryFor = (legacyTarget) => {
|
|
|
11270
11506
|
if (legacyTarget === "create-quotation") {
|
|
11271
11507
|
return 'Create a quotation with an approved supplier using --payload JSON. Include projectId, budgetId, supplierId, budgetItemIds, amountWithoutGst, gstAmount, and one uploaded attachment in attachments. Multiple budget items require lineAmounts: [{"budgetItemId":"<first-id>","amount":750},{"budgetItemId":"<second-id>","amount":450}], covering every selected budget-item ID exactly once and summing to amountWithoutGst. Amounts exclude GST; use gstAmount: 0 for no GST. Example: amountWithoutGst: 1200 with line amounts 750 and 450.';
|
|
11272
11508
|
}
|
|
11509
|
+
if (legacyTarget === "cleanup-staged-quotation-attachments")
|
|
11510
|
+
return "Queue independent cleanup operations for unattached staged quotation uploads; returns operation IDs and queued/skipped counts, not deletion confirmation. Arguments: <projectId> --keys <csv>.";
|
|
11273
11511
|
if (legacyTarget === "update-quotation") {
|
|
11274
11512
|
return 'Update a DRAFT or REJECTED quotation using --payload JSON with id and the complete creation payload. Multiple budget items require lineAmounts: [{"budgetItemId":"<first-id>","amount":750},{"budgetItemId":"<second-id>","amount":450}], covering every budgetItemIds entry exactly once and summing to amountWithoutGst. Amounts exclude GST; use gstAmount: 0 for no GST.';
|
|
11275
11513
|
}
|
|
@@ -11279,6 +11517,32 @@ var summaryFor = (legacyTarget) => {
|
|
|
11279
11517
|
if (legacyTarget === "send-customer-invoice-to-contact-person") {
|
|
11280
11518
|
return "Send a customer invoice and update the project billing email.";
|
|
11281
11519
|
}
|
|
11520
|
+
if (legacyTarget === "update-company")
|
|
11521
|
+
return "Save company fields in BB and queue independent QuickBooks name/website synchronization; returns operation ID, not provider completion.";
|
|
11522
|
+
if (legacyTarget === "get-company-quickbooks-sync-status")
|
|
11523
|
+
return "Read saved company synchronization status without provider calls or polling; use companyId.";
|
|
11524
|
+
if (legacyTarget === "get-item-quickbooks-sync-status")
|
|
11525
|
+
return "Read saved item QuickBooks synchronization status without provider calls or polling; use itemId.";
|
|
11526
|
+
if (legacyTarget === "create-webhook-endpoint")
|
|
11527
|
+
return "Admin-only: subscribe an HTTPS endpoint to BB events. --name --url --events <type|prefix.*|*,...>. Prints the whsec_ signing secret once; deliveries use Standard Webhooks headers.";
|
|
11528
|
+
if (legacyTarget === "rotate-webhook-secret")
|
|
11529
|
+
return "Admin-only: issue a new signing secret; older secrets keep signing for --previousSecretTtlHours (default 24). Prints the new secret once. Argument: <endpointId>.";
|
|
11530
|
+
if (legacyTarget === "send-webhook-test-event")
|
|
11531
|
+
return "Admin-only: send a signed webhook.test event to one endpoint. Argument: <endpointId>.";
|
|
11532
|
+
if (legacyTarget === "replay-webhook-delivery")
|
|
11533
|
+
return "Admin-only: resend a finished webhook delivery with the same eventId on a fresh attempt chain. Argument: <deliveryId>.";
|
|
11534
|
+
if (legacyTarget === "get-error")
|
|
11535
|
+
return "Admin-only: one error log with full diagnostics (stack, cause, request details, metadata, AI summary, resolution). Argument: <errorId>. error recent list returns table columns only.";
|
|
11536
|
+
if (legacyTarget === "get-webhook-delivery")
|
|
11537
|
+
return "Admin-only: one webhook delivery with payload and attempts (status codes, errors, durations). Argument: <deliveryId>.";
|
|
11538
|
+
if (legacyTarget === "list-webhook-event-types")
|
|
11539
|
+
return "List the outbound webhook event catalogue with group and live/planned status.";
|
|
11540
|
+
if (legacyTarget === "reconcile-resource-operation")
|
|
11541
|
+
return "Admin-only check of a saved QuickBooks invoice/company/item job outcome; reads the provider only when uncertain. Applied changes are finished locally without repeating the provider mutation; provably unapplied ones are queued again. Argument: <operationId>.";
|
|
11542
|
+
if (legacyTarget === "get-integration-operation")
|
|
11543
|
+
return "Admin-only read of one integration job: who queued it, the records it is for with app links, saved QuickBooks progress, admin actions and Retry state. No provider calls. Argument: <operationId>.";
|
|
11544
|
+
if (legacyTarget === "retry-integration-operation")
|
|
11545
|
+
return "Admin-only retry of a failed integration job. QuickBooks jobs with a saved attempt check QuickBooks first: applied changes finish without resending, provably unapplied ones are sent again, unprovable ones stay stopped with the reason. Argument: <operationId>.";
|
|
11282
11546
|
if (legacyTarget.startsWith("list-")) {
|
|
11283
11547
|
return `List ${legacyTarget.slice("list-".length).replaceAll("-", " ")}.`;
|
|
11284
11548
|
}
|
|
@@ -11329,6 +11593,24 @@ var registry2 = [
|
|
|
11329
11593
|
authCommand("logout", "Revoke the interactive CLI session and remove its local credential."),
|
|
11330
11594
|
legacyCommand("whoami", ["auth", "whoami"]),
|
|
11331
11595
|
legacyCommand("list-budgets", ["budget", "list"], [], [
|
|
11596
|
+
{
|
|
11597
|
+
name: "--active <true|false|all>",
|
|
11598
|
+
description: "Omit for active budgets only; false or all requires Admin access."
|
|
11599
|
+
},
|
|
11600
|
+
{
|
|
11601
|
+
name: "--limit <1-100>",
|
|
11602
|
+
description: "Rows per page. Output is { items, pageInfo }."
|
|
11603
|
+
},
|
|
11604
|
+
{
|
|
11605
|
+
name: "--cursor <token>",
|
|
11606
|
+
description: "pageInfo.nextCursor (or previousCursor with --direction backward) from the last page, unchanged; keep the same filters and sort."
|
|
11607
|
+
},
|
|
11608
|
+
{
|
|
11609
|
+
name: "--direction <forward|backward>",
|
|
11610
|
+
description: "forward (default) or backward; backward needs --cursor."
|
|
11611
|
+
}
|
|
11612
|
+
]),
|
|
11613
|
+
legacyCommand("count-budgets", ["budget", "count"], [], [
|
|
11332
11614
|
{
|
|
11333
11615
|
name: "--active <true|false|all>",
|
|
11334
11616
|
description: "Omit for active budgets only; false or all requires Admin access."
|
|
@@ -11354,7 +11636,20 @@ var registry2 = [
|
|
|
11354
11636
|
description: "Include inactive historical budgets; Admin only."
|
|
11355
11637
|
}
|
|
11356
11638
|
]),
|
|
11357
|
-
legacyCommand("get-budget-categories", ["budget", "category", "list"]
|
|
11639
|
+
legacyCommand("get-budget-categories", ["budget", "category", "list"], [], [
|
|
11640
|
+
{
|
|
11641
|
+
name: "--q <text>",
|
|
11642
|
+
description: "Search active category names (name A\u2013Z). A bare --q is rejected; use -q/--quiet to hide logs."
|
|
11643
|
+
},
|
|
11644
|
+
{
|
|
11645
|
+
name: "--limit <1-100>",
|
|
11646
|
+
description: "Rows per page. Output is { items, pageInfo }."
|
|
11647
|
+
},
|
|
11648
|
+
{
|
|
11649
|
+
name: "--cursor <token>",
|
|
11650
|
+
description: "pageInfo.nextCursor from the last page, unchanged; pages forward only."
|
|
11651
|
+
}
|
|
11652
|
+
]),
|
|
11358
11653
|
legacyCommand("get-budget-versions", ["budget", "version", "list"], [], [
|
|
11359
11654
|
{
|
|
11360
11655
|
name: "--limit <1-50>",
|
|
@@ -11414,8 +11709,36 @@ var registry2 = [
|
|
|
11414
11709
|
"placeholder-bill",
|
|
11415
11710
|
"create"
|
|
11416
11711
|
]),
|
|
11417
|
-
legacyCommand("list-bills", ["bill", "list"]
|
|
11418
|
-
|
|
11712
|
+
legacyCommand("list-bills", ["bill", "list"], [], [
|
|
11713
|
+
{
|
|
11714
|
+
name: "--limit <1-100>",
|
|
11715
|
+
description: "Rows per page. Output is { items, pageInfo }."
|
|
11716
|
+
},
|
|
11717
|
+
{
|
|
11718
|
+
name: "--cursor <token>",
|
|
11719
|
+
description: "pageInfo.nextCursor (or previousCursor with --direction backward) from the last page, unchanged; keep the same filters and sort."
|
|
11720
|
+
},
|
|
11721
|
+
{
|
|
11722
|
+
name: "--direction <forward|backward>",
|
|
11723
|
+
description: "forward (default) or backward; backward needs --cursor."
|
|
11724
|
+
}
|
|
11725
|
+
]),
|
|
11726
|
+
legacyCommand("list-claims", ["claim", "list"], [], [
|
|
11727
|
+
{
|
|
11728
|
+
name: "--limit <1-100>",
|
|
11729
|
+
description: "Rows per page. Output is { items, pageInfo }."
|
|
11730
|
+
},
|
|
11731
|
+
{
|
|
11732
|
+
name: "--cursor <token>",
|
|
11733
|
+
description: "pageInfo.nextCursor (or previousCursor with --direction backward) from the last page, unchanged; keep the same filters and sort."
|
|
11734
|
+
},
|
|
11735
|
+
{
|
|
11736
|
+
name: "--direction <forward|backward>",
|
|
11737
|
+
description: "forward (default) or backward; backward needs --cursor."
|
|
11738
|
+
}
|
|
11739
|
+
]),
|
|
11740
|
+
legacyCommand("count-bills", ["bill", "count"]),
|
|
11741
|
+
legacyCommand("count-claims", ["claim", "count"]),
|
|
11419
11742
|
legacyCommand("create-bill-approval", ["bill", "approval", "create"]),
|
|
11420
11743
|
legacyCommand("create-bill", ["bill", "create"], [], [
|
|
11421
11744
|
{
|
|
@@ -11471,7 +11794,16 @@ var registry2 = [
|
|
|
11471
11794
|
"invoice-number",
|
|
11472
11795
|
"patch"
|
|
11473
11796
|
]),
|
|
11474
|
-
legacyCommand("get-bill-attachments", ["bill", "attachment", "list"]
|
|
11797
|
+
legacyCommand("get-bill-attachments", ["bill", "attachment", "list"], [], [
|
|
11798
|
+
{
|
|
11799
|
+
name: "--limit <1-50>",
|
|
11800
|
+
description: "Rows per page. Output is { items, pageInfo }."
|
|
11801
|
+
},
|
|
11802
|
+
{
|
|
11803
|
+
name: "--cursor <token>",
|
|
11804
|
+
description: "pageInfo.nextCursor from the last page, unchanged; pages forward only."
|
|
11805
|
+
}
|
|
11806
|
+
]),
|
|
11475
11807
|
legacyCommand("stage-bill-attachment", ["bill", "attachment", "stage"]),
|
|
11476
11808
|
legacyCommand("cleanup-staged-bill-attachments", [
|
|
11477
11809
|
"bill",
|
|
@@ -11487,8 +11819,53 @@ var registry2 = [
|
|
|
11487
11819
|
]),
|
|
11488
11820
|
legacyCommand("attach-bill-documents", ["bill", "document", "attach"]),
|
|
11489
11821
|
legacyCommand("get-bill-details", ["bill", "get"]),
|
|
11490
|
-
legacyCommand("
|
|
11822
|
+
legacyCommand("get-bill-line-items", ["bill", "line-item", "list"], [], [
|
|
11823
|
+
{
|
|
11824
|
+
name: "--limit <1-100>",
|
|
11825
|
+
description: "Rows per page. Output is { items, pageInfo }."
|
|
11826
|
+
},
|
|
11827
|
+
{
|
|
11828
|
+
name: "--cursor <token>",
|
|
11829
|
+
description: "pageInfo.nextCursor from the last page, unchanged; pages forward only."
|
|
11830
|
+
}
|
|
11831
|
+
]),
|
|
11832
|
+
legacyCommand("get-bill-approvals", ["bill", "approval", "list"], [], [
|
|
11833
|
+
{
|
|
11834
|
+
name: "--limit <1-50>",
|
|
11835
|
+
description: "Rows per page. Output is { items, pageInfo }."
|
|
11836
|
+
},
|
|
11837
|
+
{
|
|
11838
|
+
name: "--cursor <token>",
|
|
11839
|
+
description: "pageInfo.nextCursor from the last page, unchanged; pages forward only."
|
|
11840
|
+
}
|
|
11841
|
+
]),
|
|
11842
|
+
legacyCommand("get-bill-payment", ["bill", "payment", "get"]),
|
|
11843
|
+
legacyCommand("list-quotations", ["quotation", "list"], [], [
|
|
11844
|
+
{
|
|
11845
|
+
name: "--limit <1-100>",
|
|
11846
|
+
description: "Rows per page. Output is { items, pageInfo }."
|
|
11847
|
+
},
|
|
11848
|
+
{
|
|
11849
|
+
name: "--cursor <token>",
|
|
11850
|
+
description: "pageInfo.nextCursor (or previousCursor with --direction backward) from the last page, unchanged; keep the same filters and sort."
|
|
11851
|
+
},
|
|
11852
|
+
{
|
|
11853
|
+
name: "--direction <forward|backward>",
|
|
11854
|
+
description: "forward (default) or backward; backward needs --cursor."
|
|
11855
|
+
}
|
|
11856
|
+
]),
|
|
11857
|
+
legacyCommand("count-quotations", ["quotation", "count"]),
|
|
11491
11858
|
legacyCommand("get-quotation", ["quotation", "get"]),
|
|
11859
|
+
legacyCommand("get-quotation-line-items", ["quotation", "line-item", "list"], [], [
|
|
11860
|
+
{
|
|
11861
|
+
name: "--limit <1-100>",
|
|
11862
|
+
description: "Rows per page. Output is { items, pageInfo }."
|
|
11863
|
+
},
|
|
11864
|
+
{
|
|
11865
|
+
name: "--cursor <token>",
|
|
11866
|
+
description: "pageInfo.nextCursor from the last page, unchanged; pages forward only."
|
|
11867
|
+
}
|
|
11868
|
+
]),
|
|
11492
11869
|
legacyCommand("upload-quotation-attachment", [
|
|
11493
11870
|
"quotation",
|
|
11494
11871
|
"attachment",
|
|
@@ -11539,8 +11916,57 @@ var registry2 = [
|
|
|
11539
11916
|
"existing",
|
|
11540
11917
|
"list"
|
|
11541
11918
|
]),
|
|
11542
|
-
legacyCommand("list-customer-invoices", ["customer-invoice", "list"]
|
|
11919
|
+
legacyCommand("list-customer-invoices", ["customer-invoice", "list"], [], [
|
|
11920
|
+
{
|
|
11921
|
+
name: "--limit <1-100>",
|
|
11922
|
+
description: "Rows per page. Output is { items, pageInfo }."
|
|
11923
|
+
},
|
|
11924
|
+
{
|
|
11925
|
+
name: "--cursor <token>",
|
|
11926
|
+
description: "pageInfo.nextCursor (or previousCursor with --direction backward) from the last page, unchanged; keep the same filters and sort."
|
|
11927
|
+
},
|
|
11928
|
+
{
|
|
11929
|
+
name: "--direction <forward|backward>",
|
|
11930
|
+
description: "forward (default) or backward; backward needs --cursor."
|
|
11931
|
+
}
|
|
11932
|
+
]),
|
|
11933
|
+
legacyCommand("count-customer-invoices", ["customer-invoice", "count"]),
|
|
11543
11934
|
legacyCommand("get-customer-invoice", ["customer-invoice", "get"]),
|
|
11935
|
+
legacyCommand("get-customer-invoice-invoices", [
|
|
11936
|
+
"customer-invoice",
|
|
11937
|
+
"invoice",
|
|
11938
|
+
"list"
|
|
11939
|
+
]),
|
|
11940
|
+
legacyCommand("get-customer-invoice-lines", ["customer-invoice", "line", "list"], [], [
|
|
11941
|
+
{
|
|
11942
|
+
name: "--limit <1-100>",
|
|
11943
|
+
description: "Rows per page. Output is { items, pageInfo }."
|
|
11944
|
+
},
|
|
11945
|
+
{
|
|
11946
|
+
name: "--cursor <token>",
|
|
11947
|
+
description: "pageInfo.nextCursor from the last page, unchanged; pages forward only."
|
|
11948
|
+
}
|
|
11949
|
+
]),
|
|
11950
|
+
legacyCommand("get-customer-invoice-approvals", ["customer-invoice", "approval", "list"], [], [
|
|
11951
|
+
{
|
|
11952
|
+
name: "--limit <1-50>",
|
|
11953
|
+
description: "Rows per page. Output is { items, pageInfo }."
|
|
11954
|
+
},
|
|
11955
|
+
{
|
|
11956
|
+
name: "--cursor <token>",
|
|
11957
|
+
description: "pageInfo.nextCursor from the last page, unchanged; pages forward only."
|
|
11958
|
+
}
|
|
11959
|
+
]),
|
|
11960
|
+
legacyCommand("get-customer-invoice-history", ["customer-invoice", "history", "list"], [], [
|
|
11961
|
+
{
|
|
11962
|
+
name: "--limit <1-100>",
|
|
11963
|
+
description: "Rows per page. Output is { items, pageInfo }."
|
|
11964
|
+
},
|
|
11965
|
+
{
|
|
11966
|
+
name: "--cursor <token>",
|
|
11967
|
+
description: "pageInfo.nextCursor from the last page, unchanged; pages forward only."
|
|
11968
|
+
}
|
|
11969
|
+
]),
|
|
11544
11970
|
legacyCommand("get-customer-invoice-email-context", [
|
|
11545
11971
|
"customer-invoice",
|
|
11546
11972
|
"email-context",
|
|
@@ -11578,7 +12004,62 @@ var registry2 = [
|
|
|
11578
12004
|
legacyCommand("approve-supplier", ["supplier", "approve"]),
|
|
11579
12005
|
legacyCommand("reject-supplier", ["supplier", "reject"]),
|
|
11580
12006
|
legacyCommand("get-supplier-details", ["supplier", "detail", "get"]),
|
|
11581
|
-
legacyCommand("list-companies", ["company", "list"]
|
|
12007
|
+
legacyCommand("list-companies", ["company", "list"], [], [
|
|
12008
|
+
{
|
|
12009
|
+
name: "--name <text>",
|
|
12010
|
+
description: "Filter by company name substring."
|
|
12011
|
+
},
|
|
12012
|
+
{
|
|
12013
|
+
name: "--createdBy <userId>",
|
|
12014
|
+
description: "Filter by one creator user ID."
|
|
12015
|
+
},
|
|
12016
|
+
{
|
|
12017
|
+
name: "--createdByIds <csv>",
|
|
12018
|
+
description: "Filter by a comma-separated creator user ID list."
|
|
12019
|
+
},
|
|
12020
|
+
{
|
|
12021
|
+
name: "--active <true|false>",
|
|
12022
|
+
description: "Filter by active status; omit to include both states."
|
|
12023
|
+
},
|
|
12024
|
+
{
|
|
12025
|
+
name: "--sortBy <name|createdAt>",
|
|
12026
|
+
description: "Sort field (default createdAt)."
|
|
12027
|
+
},
|
|
12028
|
+
{
|
|
12029
|
+
name: "--sortDir <asc|desc>",
|
|
12030
|
+
description: "Sort direction (default desc)."
|
|
12031
|
+
},
|
|
12032
|
+
{
|
|
12033
|
+
name: "--limit <1-100>",
|
|
12034
|
+
description: "Bounded page size (default 20)."
|
|
12035
|
+
},
|
|
12036
|
+
{
|
|
12037
|
+
name: "--cursor <token>",
|
|
12038
|
+
description: "Opaque pageInfo cursor; pass nextCursor forward or previousCursor backward unchanged."
|
|
12039
|
+
},
|
|
12040
|
+
{
|
|
12041
|
+
name: "--direction <forward|backward>",
|
|
12042
|
+
description: "Use forward by default; backward requires --cursor."
|
|
12043
|
+
}
|
|
12044
|
+
]),
|
|
12045
|
+
legacyCommand("count-companies", ["company", "count"], [], [
|
|
12046
|
+
{
|
|
12047
|
+
name: "--name <text>",
|
|
12048
|
+
description: "Filter by company name substring."
|
|
12049
|
+
},
|
|
12050
|
+
{
|
|
12051
|
+
name: "--createdBy <userId>",
|
|
12052
|
+
description: "Filter by one creator user ID."
|
|
12053
|
+
},
|
|
12054
|
+
{
|
|
12055
|
+
name: "--createdByIds <csv>",
|
|
12056
|
+
description: "Filter by a comma-separated creator user ID list."
|
|
12057
|
+
},
|
|
12058
|
+
{
|
|
12059
|
+
name: "--active <true|false>",
|
|
12060
|
+
description: "Filter by active status; facets omit this self-filter."
|
|
12061
|
+
}
|
|
12062
|
+
]),
|
|
11582
12063
|
legacyCommand("get-company", ["company", "get"]),
|
|
11583
12064
|
legacyCommand("search-existing-companies", ["company", "search"], [], [
|
|
11584
12065
|
{
|
|
@@ -11586,8 +12067,12 @@ var registry2 = [
|
|
|
11586
12067
|
description: "Company name to search in BB and QuickBooks."
|
|
11587
12068
|
},
|
|
11588
12069
|
{
|
|
11589
|
-
name: "--
|
|
11590
|
-
description: "
|
|
12070
|
+
name: "--limit",
|
|
12071
|
+
description: "Matches per page, 1\u201350 (default 8)."
|
|
12072
|
+
},
|
|
12073
|
+
{
|
|
12074
|
+
name: "--cursor",
|
|
12075
|
+
description: "pageInfo.nextCursor from the previous page, unchanged."
|
|
11591
12076
|
}
|
|
11592
12077
|
]),
|
|
11593
12078
|
legacyCommand("use-existing-company", ["company", "use"], [], [
|
|
@@ -11615,8 +12100,94 @@ var registry2 = [
|
|
|
11615
12100
|
}
|
|
11616
12101
|
]),
|
|
11617
12102
|
legacyCommand("update-company", ["company", "update"]),
|
|
12103
|
+
legacyCommand("get-company-quickbooks-sync-status", [
|
|
12104
|
+
"company",
|
|
12105
|
+
"sync",
|
|
12106
|
+
"status"
|
|
12107
|
+
]),
|
|
11618
12108
|
legacyCommand("delete-company", ["company", "delete"]),
|
|
11619
|
-
legacyCommand("list-projects", ["project", "list"]
|
|
12109
|
+
legacyCommand("list-projects", ["project", "list"], [], [
|
|
12110
|
+
{ name: "--companyId <id>", description: "Filter by company ID." },
|
|
12111
|
+
{
|
|
12112
|
+
name: "--name <text>",
|
|
12113
|
+
description: "Filter by project name substring."
|
|
12114
|
+
},
|
|
12115
|
+
{
|
|
12116
|
+
name: "--status <status|ALL>",
|
|
12117
|
+
description: "Legacy single-status filter; use --statuses for multiple statuses."
|
|
12118
|
+
},
|
|
12119
|
+
{
|
|
12120
|
+
name: "--statuses <csv>",
|
|
12121
|
+
description: "Filter by a comma-separated project status list."
|
|
12122
|
+
},
|
|
12123
|
+
{
|
|
12124
|
+
name: "--active <true|false>",
|
|
12125
|
+
description: "Filter by active status; omit to include both states."
|
|
12126
|
+
},
|
|
12127
|
+
{
|
|
12128
|
+
name: "--wonFrom <iso>",
|
|
12129
|
+
description: "Only projects marked WON on or after this ISO date or datetime (UTC)."
|
|
12130
|
+
},
|
|
12131
|
+
{
|
|
12132
|
+
name: "--wonTo <iso>",
|
|
12133
|
+
description: "Only projects marked WON on or before this ISO date (inclusive) or datetime (UTC)."
|
|
12134
|
+
},
|
|
12135
|
+
{
|
|
12136
|
+
name: "--wonWithinDays <1-3650>",
|
|
12137
|
+
description: "Only projects marked WON in the last N days."
|
|
12138
|
+
},
|
|
12139
|
+
{
|
|
12140
|
+
name: "--limit <1-100>",
|
|
12141
|
+
description: "Bounded page size (default 20)."
|
|
12142
|
+
},
|
|
12143
|
+
{
|
|
12144
|
+
name: "--cursor <token>",
|
|
12145
|
+
description: "Opaque pageInfo cursor; pass nextCursor forward or previousCursor backward unchanged."
|
|
12146
|
+
},
|
|
12147
|
+
{
|
|
12148
|
+
name: "--direction <forward|backward>",
|
|
12149
|
+
description: "Use forward by default; backward requires --cursor."
|
|
12150
|
+
},
|
|
12151
|
+
{
|
|
12152
|
+
name: "--sortBy <name|createdAt|status|companyName|wonAt>",
|
|
12153
|
+
description: "Sort field (default createdAt); wonAt puts unwon projects last."
|
|
12154
|
+
},
|
|
12155
|
+
{
|
|
12156
|
+
name: "--sortDir <asc|desc>",
|
|
12157
|
+
description: "Sort direction (default desc)."
|
|
12158
|
+
}
|
|
12159
|
+
]),
|
|
12160
|
+
legacyCommand("count-projects", ["project", "count"], [], [
|
|
12161
|
+
{ name: "--companyId <id>", description: "Filter by company ID." },
|
|
12162
|
+
{
|
|
12163
|
+
name: "--name <text>",
|
|
12164
|
+
description: "Filter by project name substring."
|
|
12165
|
+
},
|
|
12166
|
+
{
|
|
12167
|
+
name: "--status <status|ALL>",
|
|
12168
|
+
description: "Legacy single-status filter."
|
|
12169
|
+
},
|
|
12170
|
+
{
|
|
12171
|
+
name: "--statuses <csv>",
|
|
12172
|
+
description: "Filter by a comma-separated project status list."
|
|
12173
|
+
},
|
|
12174
|
+
{
|
|
12175
|
+
name: "--active <true|false>",
|
|
12176
|
+
description: "Filter by active status; facets exclude this self-filter."
|
|
12177
|
+
},
|
|
12178
|
+
{
|
|
12179
|
+
name: "--wonFrom <iso>",
|
|
12180
|
+
description: "Only projects marked WON on or after this ISO date or datetime (UTC)."
|
|
12181
|
+
},
|
|
12182
|
+
{
|
|
12183
|
+
name: "--wonTo <iso>",
|
|
12184
|
+
description: "Only projects marked WON on or before this ISO date (inclusive) or datetime (UTC)."
|
|
12185
|
+
},
|
|
12186
|
+
{
|
|
12187
|
+
name: "--wonWithinDays <1-3650>",
|
|
12188
|
+
description: "Only projects marked WON in the last N days."
|
|
12189
|
+
}
|
|
12190
|
+
]),
|
|
11620
12191
|
legacyCommand("list-project-hubs", ["project", "hub", "list"], [], [
|
|
11621
12192
|
{
|
|
11622
12193
|
name: "--q",
|
|
@@ -11626,14 +12197,31 @@ var registry2 = [
|
|
|
11626
12197
|
name: "--status",
|
|
11627
12198
|
description: "Filter by comma-separated project statuses."
|
|
11628
12199
|
},
|
|
11629
|
-
{ name: "--
|
|
11630
|
-
{
|
|
12200
|
+
{ name: "--limit", description: "Page size, 1-100 (default 20)." },
|
|
12201
|
+
{
|
|
12202
|
+
name: "--cursor",
|
|
12203
|
+
description: "Opaque nextCursor/previousCursor from the last page."
|
|
12204
|
+
},
|
|
12205
|
+
{
|
|
12206
|
+
name: "--direction",
|
|
12207
|
+
description: "forward (default) or backward; backward needs --cursor."
|
|
12208
|
+
},
|
|
11631
12209
|
{
|
|
11632
12210
|
name: "--sortBy",
|
|
11633
12211
|
description: "Sort by startDate, name, companyName, or status."
|
|
11634
12212
|
},
|
|
11635
12213
|
{ name: "--sortDir", description: "Sort in asc or desc order." }
|
|
11636
12214
|
]),
|
|
12215
|
+
legacyCommand("count-project-hubs", ["project", "hub", "count"], [], [
|
|
12216
|
+
{
|
|
12217
|
+
name: "--q",
|
|
12218
|
+
description: "Search project and company names."
|
|
12219
|
+
},
|
|
12220
|
+
{
|
|
12221
|
+
name: "--status",
|
|
12222
|
+
description: "Filter by comma-separated project statuses."
|
|
12223
|
+
}
|
|
12224
|
+
]),
|
|
11637
12225
|
legacyCommand("get-project", ["project", "get"]),
|
|
11638
12226
|
legacyCommand("get-project-hub-status", ["project", "hub", "status"]),
|
|
11639
12227
|
legacyCommand("setup-project-hub", ["project", "hub", "setup"]),
|
|
@@ -11657,7 +12245,67 @@ var registry2 = [
|
|
|
11657
12245
|
legacyCommand("list-contacts", ["contact", "list"]),
|
|
11658
12246
|
legacyCommand("create-contact-person", ["contact", "create"]),
|
|
11659
12247
|
legacyCommand("update-contact-person", ["contact", "update"]),
|
|
11660
|
-
legacyCommand("list-suppliers", ["supplier", "list"]
|
|
12248
|
+
legacyCommand("list-suppliers", ["supplier", "list"], [], [
|
|
12249
|
+
{ name: "--name <text>", description: "Filter supplier name or email." },
|
|
12250
|
+
{ name: "--createdBy <csv>", description: "Filter by creator IDs." },
|
|
12251
|
+
{
|
|
12252
|
+
name: "--gstRegistered <true|false>",
|
|
12253
|
+
description: "Filter GST registration."
|
|
12254
|
+
},
|
|
12255
|
+
{
|
|
12256
|
+
name: "--status <csv>",
|
|
12257
|
+
description: "Filter approval statuses; ALL means no status filter."
|
|
12258
|
+
},
|
|
12259
|
+
{
|
|
12260
|
+
name: "--supplierTags <csv>",
|
|
12261
|
+
description: "Filter by supplier tag IDs."
|
|
12262
|
+
},
|
|
12263
|
+
{
|
|
12264
|
+
name: "--active <true|false>",
|
|
12265
|
+
description: "Active by default; false selects archived."
|
|
12266
|
+
},
|
|
12267
|
+
{
|
|
12268
|
+
name: "--limit <1-100>",
|
|
12269
|
+
description: "Bounded page size (default 10). Retired page/perPage flags are rejected."
|
|
12270
|
+
},
|
|
12271
|
+
{
|
|
12272
|
+
name: "--cursor <token>",
|
|
12273
|
+
description: "Opaque nextCursor or previousCursor from items/pageInfo."
|
|
12274
|
+
},
|
|
12275
|
+
{
|
|
12276
|
+
name: "--direction <forward|backward>",
|
|
12277
|
+
description: "Forward by default; backward requires a cursor."
|
|
12278
|
+
},
|
|
12279
|
+
{
|
|
12280
|
+
name: "--sortBy <field>",
|
|
12281
|
+
description: "name, email, phone, gstRegistered, status, active, createdAt or updatedAt."
|
|
12282
|
+
},
|
|
12283
|
+
{
|
|
12284
|
+
name: "--sortDir <asc|desc>",
|
|
12285
|
+
description: "Descending createdAt by default."
|
|
12286
|
+
},
|
|
12287
|
+
{
|
|
12288
|
+
name: "--sort <json>",
|
|
12289
|
+
description: "Ordered {id,desc} array for multi-column sorting; cannot combine with sortBy/sortDir."
|
|
12290
|
+
}
|
|
12291
|
+
]),
|
|
12292
|
+
legacyCommand("count-suppliers", ["supplier", "count"], [], [
|
|
12293
|
+
{ name: "--name <text>", description: "Filter supplier name or email." },
|
|
12294
|
+
{ name: "--createdBy <csv>", description: "Filter by creator IDs." },
|
|
12295
|
+
{
|
|
12296
|
+
name: "--gstRegistered <true|false>",
|
|
12297
|
+
description: "Filter GST registration."
|
|
12298
|
+
},
|
|
12299
|
+
{ name: "--status <csv>", description: "Filter approval statuses." },
|
|
12300
|
+
{
|
|
12301
|
+
name: "--supplierTags <csv>",
|
|
12302
|
+
description: "Filter by supplier tag IDs."
|
|
12303
|
+
},
|
|
12304
|
+
{
|
|
12305
|
+
name: "--active <true|false>",
|
|
12306
|
+
description: "Active by default; false selects archived. No pagination/sort flags."
|
|
12307
|
+
}
|
|
12308
|
+
]),
|
|
11661
12309
|
legacyCommand("create-supplier", ["supplier", "create"]),
|
|
11662
12310
|
legacyCommand("update-supplier", ["supplier", "update"]),
|
|
11663
12311
|
legacyCommand("delete-suppliers", ["supplier", "delete"]),
|
|
@@ -11674,21 +12322,87 @@ var registry2 = [
|
|
|
11674
12322
|
]),
|
|
11675
12323
|
legacyCommand("create-supplier-role", ["supplier", "role", "create"]),
|
|
11676
12324
|
legacyCommand("create-supplier-tag", ["supplier", "tag", "create"]),
|
|
11677
|
-
legacyCommand("get-supplier-analytics", ["supplier", "analytics", "get"]
|
|
11678
|
-
|
|
12325
|
+
legacyCommand("get-supplier-analytics", ["supplier", "analytics", "get"], [], [
|
|
12326
|
+
{
|
|
12327
|
+
name: "--limit <1-100>",
|
|
12328
|
+
description: "Rows per page. Output is { items, pageInfo }."
|
|
12329
|
+
},
|
|
12330
|
+
{
|
|
12331
|
+
name: "--cursor <token>",
|
|
12332
|
+
description: "pageInfo.nextCursor (or previousCursor with --direction backward) from the last page, unchanged; keep the same filters and sort."
|
|
12333
|
+
},
|
|
12334
|
+
{
|
|
12335
|
+
name: "--direction <forward|backward>",
|
|
12336
|
+
description: "forward (default) or backward; backward needs --cursor."
|
|
12337
|
+
}
|
|
12338
|
+
]),
|
|
12339
|
+
legacyCommand("count-supplier-analytics", ["supplier", "analytics", "count"]),
|
|
12340
|
+
legacyCommand("list-items", ["item", "list"], [], [
|
|
12341
|
+
{
|
|
12342
|
+
name: "--limit <1-100>",
|
|
12343
|
+
description: "Rows per page. Output is { items, pageInfo }."
|
|
12344
|
+
},
|
|
12345
|
+
{
|
|
12346
|
+
name: "--cursor <token>",
|
|
12347
|
+
description: "pageInfo.nextCursor (or previousCursor with --direction backward) from the last page, unchanged; keep the same filters and sort."
|
|
12348
|
+
},
|
|
12349
|
+
{
|
|
12350
|
+
name: "--direction <forward|backward>",
|
|
12351
|
+
description: "forward (default) or backward; backward needs --cursor."
|
|
12352
|
+
}
|
|
12353
|
+
]),
|
|
12354
|
+
legacyCommand("count-items", ["item", "count"]),
|
|
11679
12355
|
legacyCommand("get-item", ["item", "get"]),
|
|
12356
|
+
legacyCommand("get-item-quickbooks-sync-status", ["item", "sync", "status"]),
|
|
11680
12357
|
legacyCommand("create-item", ["item", "create"]),
|
|
11681
12358
|
legacyCommand("update-item", ["item", "update"]),
|
|
11682
12359
|
legacyCommand("archive-items", ["item", "archive"]),
|
|
11683
12360
|
legacyCommand("delete-item", ["item", "delete"]),
|
|
11684
|
-
legacyCommand("list-item-categories", ["item", "category", "list"]
|
|
12361
|
+
legacyCommand("list-item-categories", ["item", "category", "list"], [], [
|
|
12362
|
+
{
|
|
12363
|
+
name: "--limit <1-100>",
|
|
12364
|
+
description: "Rows per page. Output is { items, pageInfo }."
|
|
12365
|
+
},
|
|
12366
|
+
{
|
|
12367
|
+
name: "--cursor <token>",
|
|
12368
|
+
description: "pageInfo.nextCursor (or previousCursor with --direction backward) from the last page, unchanged; keep the same filters and sort."
|
|
12369
|
+
},
|
|
12370
|
+
{
|
|
12371
|
+
name: "--direction <forward|backward>",
|
|
12372
|
+
description: "forward (default) or backward; backward needs --cursor."
|
|
12373
|
+
}
|
|
12374
|
+
]),
|
|
12375
|
+
legacyCommand("count-item-categories", ["item", "category", "count"]),
|
|
11685
12376
|
legacyCommand("create-item-category", ["item", "category", "create"]),
|
|
11686
12377
|
legacyCommand("update-item-category", ["item", "category", "update"]),
|
|
11687
12378
|
legacyCommand("delete-item-categories", ["item", "category", "delete"]),
|
|
11688
|
-
legacyCommand("list-users", ["user", "list"]
|
|
12379
|
+
legacyCommand("list-users", ["user", "list"], [], [
|
|
12380
|
+
{
|
|
12381
|
+
name: "--q <text>",
|
|
12382
|
+
description: "Search user names and emails (name A\u2013Z). A bare --q is rejected; use -q/--quiet to hide logs."
|
|
12383
|
+
},
|
|
12384
|
+
{
|
|
12385
|
+
name: "--limit <1-100>",
|
|
12386
|
+
description: "Rows per page. Output is { items, pageInfo }."
|
|
12387
|
+
},
|
|
12388
|
+
{
|
|
12389
|
+
name: "--cursor <token>",
|
|
12390
|
+
description: "pageInfo.nextCursor from the last page, unchanged; pages forward only."
|
|
12391
|
+
}
|
|
12392
|
+
]),
|
|
12393
|
+
legacyCommand("count-users", ["user", "count"]),
|
|
11689
12394
|
legacyCommand("create-user", ["user", "create"]),
|
|
11690
12395
|
legacyCommand("create-api-key", ["user", "api-key", "create"]),
|
|
11691
|
-
legacyCommand("list-api-keys", ["user", "api-key", "list"]
|
|
12396
|
+
legacyCommand("list-api-keys", ["user", "api-key", "list"], [], [
|
|
12397
|
+
{
|
|
12398
|
+
name: "--limit <1-100>",
|
|
12399
|
+
description: "Rows per page. Output is { items, pageInfo }."
|
|
12400
|
+
},
|
|
12401
|
+
{
|
|
12402
|
+
name: "--cursor <token>",
|
|
12403
|
+
description: "pageInfo.nextCursor from the last page, unchanged; pages forward only."
|
|
12404
|
+
}
|
|
12405
|
+
]),
|
|
11692
12406
|
legacyCommand("revoke-api-key", ["user", "api-key", "revoke"]),
|
|
11693
12407
|
legacyCommand("get-user-performance", ["user", "performance", "get"]),
|
|
11694
12408
|
legacyCommand("get-dashboard", ["dashboard", "get"]),
|
|
@@ -11704,23 +12418,144 @@ var registry2 = [
|
|
|
11704
12418
|
"financial-overview",
|
|
11705
12419
|
"get"
|
|
11706
12420
|
]),
|
|
11707
|
-
legacyCommand("get-recent-errors", ["error", "recent", "list"]
|
|
12421
|
+
legacyCommand("get-recent-errors", ["error", "recent", "list"], [], [
|
|
12422
|
+
{
|
|
12423
|
+
name: "--cursor <token>",
|
|
12424
|
+
description: "Pass a returned pageInfo boundary unchanged, with the same filters."
|
|
12425
|
+
},
|
|
12426
|
+
{
|
|
12427
|
+
name: "--direction <direction>",
|
|
12428
|
+
description: "forward (default) uses nextCursor; backward uses previousCursor."
|
|
12429
|
+
},
|
|
12430
|
+
{
|
|
12431
|
+
name: "--limit <number>",
|
|
12432
|
+
description: "1\u2013100 rows (default 10). Returns items and pageInfo, without a total."
|
|
12433
|
+
},
|
|
12434
|
+
{ name: "--severity <severity>", description: "Error severity or ALL." },
|
|
12435
|
+
{ name: "--status <status>", description: "Error status or ALL." },
|
|
12436
|
+
{
|
|
12437
|
+
name: "--timeFrame <period>",
|
|
12438
|
+
description: "all_time (default), last_30_days, last_3_months, last_6_months or last_1_year."
|
|
12439
|
+
}
|
|
12440
|
+
]),
|
|
12441
|
+
legacyCommand("count-errors", ["error", "recent", "count"], [], [
|
|
12442
|
+
{ name: "--severity <severity>", description: "Error severity or ALL." },
|
|
12443
|
+
{ name: "--status <status>", description: "Error status or ALL." },
|
|
12444
|
+
{
|
|
12445
|
+
name: "--timeFrame <period>",
|
|
12446
|
+
description: "Same filters as error recent list; returns independent totalCount."
|
|
12447
|
+
}
|
|
12448
|
+
]),
|
|
12449
|
+
legacyCommand("get-error", ["error", "get"]),
|
|
11708
12450
|
legacyCommand("get-error-metrics", ["error", "metrics", "get"]),
|
|
11709
|
-
legacyCommand("list-integration-operations", [
|
|
12451
|
+
legacyCommand("list-integration-operations", ["integration", "operation", "list"], [], [
|
|
12452
|
+
{
|
|
12453
|
+
name: "--limit <1-100>",
|
|
12454
|
+
description: "Rows per page. Output is { items, pageInfo }."
|
|
12455
|
+
},
|
|
12456
|
+
{
|
|
12457
|
+
name: "--cursor <token>",
|
|
12458
|
+
description: "pageInfo.nextCursor (or previousCursor with --direction backward) from the last page, unchanged; keep the same filters and sort."
|
|
12459
|
+
},
|
|
12460
|
+
{
|
|
12461
|
+
name: "--direction <forward|backward>",
|
|
12462
|
+
description: "forward (default) or backward; backward needs --cursor."
|
|
12463
|
+
}
|
|
12464
|
+
]),
|
|
12465
|
+
legacyCommand("count-integration-operations", [
|
|
11710
12466
|
"integration",
|
|
11711
12467
|
"operation",
|
|
11712
|
-
"
|
|
12468
|
+
"count"
|
|
12469
|
+
]),
|
|
12470
|
+
legacyCommand("get-integration-operation", [
|
|
12471
|
+
"integration",
|
|
12472
|
+
"operation",
|
|
12473
|
+
"get"
|
|
11713
12474
|
]),
|
|
11714
12475
|
legacyCommand("retry-integration-operation", [
|
|
11715
12476
|
"integration",
|
|
11716
12477
|
"operation",
|
|
11717
12478
|
"retry"
|
|
11718
12479
|
]),
|
|
11719
|
-
legacyCommand("
|
|
12480
|
+
legacyCommand("reconcile-resource-operation", [
|
|
12481
|
+
"integration",
|
|
12482
|
+
"operation",
|
|
12483
|
+
"reconcile-resource"
|
|
12484
|
+
]),
|
|
12485
|
+
legacyCommand("list-webhook-event-types", ["webhook", "event-type", "list"]),
|
|
12486
|
+
legacyCommand("list-webhook-endpoints", ["webhook", "endpoint", "list"]),
|
|
12487
|
+
legacyCommand("get-webhook-endpoint", ["webhook", "endpoint", "get"]),
|
|
12488
|
+
legacyCommand("create-webhook-endpoint", ["webhook", "endpoint", "create"]),
|
|
12489
|
+
legacyCommand("update-webhook-endpoint", ["webhook", "endpoint", "update"]),
|
|
12490
|
+
legacyCommand("delete-webhook-endpoint", ["webhook", "endpoint", "delete"]),
|
|
12491
|
+
legacyCommand("rotate-webhook-secret", ["webhook", "secret", "rotate"]),
|
|
12492
|
+
legacyCommand("send-webhook-test-event", ["webhook", "endpoint", "test"]),
|
|
12493
|
+
legacyCommand("list-webhook-deliveries", ["webhook", "delivery", "list"]),
|
|
12494
|
+
legacyCommand("get-webhook-delivery", ["webhook", "delivery", "get"]),
|
|
12495
|
+
legacyCommand("replay-webhook-delivery", ["webhook", "delivery", "replay"]),
|
|
12496
|
+
legacyCommand("list-inbound-sources", ["inbound", "source", "list"], [], [
|
|
12497
|
+
{
|
|
12498
|
+
name: "--limit <n>",
|
|
12499
|
+
description: "Rows per cursor page (1..100; default 25)."
|
|
12500
|
+
},
|
|
12501
|
+
{
|
|
12502
|
+
name: "--cursor <token>",
|
|
12503
|
+
description: "Opaque source continuation token returned by pageInfo."
|
|
12504
|
+
},
|
|
12505
|
+
{
|
|
12506
|
+
name: "--direction <value>",
|
|
12507
|
+
description: "forward or backward (default forward; backward requires cursor)."
|
|
12508
|
+
},
|
|
12509
|
+
{
|
|
12510
|
+
name: "--search <text>",
|
|
12511
|
+
description: "Search source name or Typeform form ID."
|
|
12512
|
+
},
|
|
12513
|
+
{
|
|
12514
|
+
name: "--processingEnabled <boolean>",
|
|
12515
|
+
description: "Filter processing enabled state."
|
|
12516
|
+
},
|
|
12517
|
+
{
|
|
12518
|
+
name: "--processingMode <mode>",
|
|
12519
|
+
description: "ACTIVE, COLLECT_ONLY or SHADOW."
|
|
12520
|
+
}
|
|
12521
|
+
]),
|
|
12522
|
+
legacyCommand("count-inbound-sources", ["inbound", "source", "count"], [], [
|
|
12523
|
+
{
|
|
12524
|
+
name: "--search <text>",
|
|
12525
|
+
description: "Search source name or Typeform form ID."
|
|
12526
|
+
},
|
|
12527
|
+
{
|
|
12528
|
+
name: "--processingEnabled <boolean>",
|
|
12529
|
+
description: "Filter processing enabled state."
|
|
12530
|
+
},
|
|
12531
|
+
{
|
|
12532
|
+
name: "--processingMode <mode>",
|
|
12533
|
+
description: "ACTIVE, COLLECT_ONLY or SHADOW."
|
|
12534
|
+
}
|
|
12535
|
+
]),
|
|
11720
12536
|
legacyCommand("create-inbound-source", ["inbound", "source", "create"]),
|
|
11721
12537
|
legacyCommand("get-inbound-source", ["inbound", "source", "get"]),
|
|
11722
12538
|
legacyCommand("update-inbound-source", ["inbound", "source", "update"]),
|
|
11723
|
-
legacyCommand("list-inbound-submissions", ["inbound", "submission", "list"]
|
|
12539
|
+
legacyCommand("list-inbound-submissions", ["inbound", "submission", "list"], [], [
|
|
12540
|
+
{
|
|
12541
|
+
name: "--limit <number>",
|
|
12542
|
+
description: "Page size from 1 to 100 (default 25). Returns submissions, hasMore and nextCursor; no total."
|
|
12543
|
+
},
|
|
12544
|
+
{
|
|
12545
|
+
name: "--cursor <token>",
|
|
12546
|
+
description: "Pass the previous response's nextCursor unchanged. Omit for newest submissions. Replaces --page/--perPage."
|
|
12547
|
+
},
|
|
12548
|
+
{
|
|
12549
|
+
name: "--sourceId <id>",
|
|
12550
|
+
description: "Filter submissions to this source; keep the same filter while following cursors."
|
|
12551
|
+
}
|
|
12552
|
+
]),
|
|
12553
|
+
legacyCommand("count-inbound-submissions", ["inbound", "submission", "count"], [], [
|
|
12554
|
+
{
|
|
12555
|
+
name: "--sourceId <id>",
|
|
12556
|
+
description: "Optional source filter. Returns an independently calculated exact totalCount, not a list snapshot."
|
|
12557
|
+
}
|
|
12558
|
+
]),
|
|
11724
12559
|
legacyCommand("get-inbound-submission", ["inbound", "submission", "get"]),
|
|
11725
12560
|
legacyCommand("save-inbound-mapping", ["inbound", "mapping", "save"]),
|
|
11726
12561
|
legacyCommand("save-inbound-automation-config", [
|
|
@@ -11893,17 +12728,292 @@ compdef _bb bb
|
|
|
11893
12728
|
`;
|
|
11894
12729
|
}
|
|
11895
12730
|
};
|
|
11896
|
-
|
|
11897
|
-
// src/cli.ts
|
|
11898
|
-
|
|
12731
|
+
|
|
12732
|
+
// src/cli.ts
|
|
12733
|
+
var SUPPLIER_ANALYTICS_SORT_IDS = [
|
|
12734
|
+
"name",
|
|
12735
|
+
"gstRegistered",
|
|
12736
|
+
"status",
|
|
12737
|
+
"phone",
|
|
12738
|
+
"email",
|
|
12739
|
+
"updatedAt",
|
|
12740
|
+
"createdAt"
|
|
12741
|
+
];
|
|
12742
|
+
function parsePositiveIntFlag(value, flagName) {
|
|
12743
|
+
if (value === undefined)
|
|
12744
|
+
return;
|
|
12745
|
+
const parsed = Number.parseInt(String(value), 10);
|
|
12746
|
+
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
12747
|
+
throw new Error(`${flagName} must be a positive integer.`);
|
|
12748
|
+
}
|
|
12749
|
+
return parsed;
|
|
12750
|
+
}
|
|
12751
|
+
var COMPANY_SORT_FIELDS = ["name", "createdAt"];
|
|
12752
|
+
var COMPANY_SORT_DIRECTIONS = ["asc", "desc"];
|
|
12753
|
+
var COMPANY_PAGE_FLAGS = [
|
|
12754
|
+
"page",
|
|
12755
|
+
"perPage",
|
|
12756
|
+
"pageSize",
|
|
12757
|
+
"page-size",
|
|
12758
|
+
"per-page",
|
|
12759
|
+
"page_size",
|
|
12760
|
+
"per_page"
|
|
12761
|
+
];
|
|
12762
|
+
var rejectBareFlag = (flags, key) => {
|
|
12763
|
+
if (flags[key] === true) {
|
|
12764
|
+
throw new Error(`--${key} requires a value.`);
|
|
12765
|
+
}
|
|
12766
|
+
};
|
|
12767
|
+
var rejectCompanyPageFlags = (flags, command) => {
|
|
12768
|
+
for (const key of COMPANY_PAGE_FLAGS) {
|
|
12769
|
+
if (flags[key] !== undefined) {
|
|
12770
|
+
throw new Error(`--${key} is not supported by company ${command}; use --limit and --cursor for list or company count for totals.`);
|
|
12771
|
+
}
|
|
12772
|
+
}
|
|
12773
|
+
};
|
|
12774
|
+
var parseCompanyLimit = (value) => {
|
|
12775
|
+
if (value === undefined)
|
|
12776
|
+
return 20;
|
|
12777
|
+
const parsed = Number(String(value));
|
|
12778
|
+
if (!Number.isInteger(parsed) || parsed < 1 || parsed > 100) {
|
|
12779
|
+
throw new Error("--limit must be an integer from 1 to 100.");
|
|
12780
|
+
}
|
|
12781
|
+
return parsed;
|
|
12782
|
+
};
|
|
12783
|
+
var parseCompanySortBy = (value) => {
|
|
12784
|
+
if (value === undefined)
|
|
12785
|
+
return "createdAt";
|
|
12786
|
+
if (!COMPANY_SORT_FIELDS.includes(value)) {
|
|
12787
|
+
throw new Error(`Invalid --sortBy "${value}". Use one of: ${COMPANY_SORT_FIELDS.join(", ")}.`);
|
|
12788
|
+
}
|
|
12789
|
+
return value;
|
|
12790
|
+
};
|
|
12791
|
+
var parseCompanySortDir = (value) => {
|
|
12792
|
+
if (value === undefined)
|
|
12793
|
+
return "desc";
|
|
12794
|
+
if (!COMPANY_SORT_DIRECTIONS.includes(value)) {
|
|
12795
|
+
throw new Error(`Invalid --sortDir "${value}". Use one of: ${COMPANY_SORT_DIRECTIONS.join(", ")}.`);
|
|
12796
|
+
}
|
|
12797
|
+
return value;
|
|
12798
|
+
};
|
|
12799
|
+
var parseCompanyDirection = (value) => {
|
|
12800
|
+
if (value === undefined)
|
|
12801
|
+
return "forward";
|
|
12802
|
+
if (value !== "forward" && value !== "backward") {
|
|
12803
|
+
throw new Error('--direction must be "forward" or "backward".');
|
|
12804
|
+
}
|
|
12805
|
+
return value;
|
|
12806
|
+
};
|
|
12807
|
+
var parseCompanyListFlags = (flags) => {
|
|
12808
|
+
rejectCompanyPageFlags(flags, "list");
|
|
12809
|
+
for (const key of [
|
|
12810
|
+
"name",
|
|
12811
|
+
"createdBy",
|
|
12812
|
+
"createdByIds",
|
|
12813
|
+
"active",
|
|
12814
|
+
"limit",
|
|
12815
|
+
"cursor",
|
|
12816
|
+
"direction",
|
|
12817
|
+
"sortBy",
|
|
12818
|
+
"sortDir"
|
|
12819
|
+
]) {
|
|
12820
|
+
rejectBareFlag(flags, key);
|
|
12821
|
+
}
|
|
12822
|
+
const cursor = getFlag(flags, "cursor");
|
|
12823
|
+
const direction = parseCompanyDirection(getFlag(flags, "direction"));
|
|
12824
|
+
if (direction === "backward" && cursor === undefined) {
|
|
12825
|
+
throw new Error("--direction backward requires --cursor <token>.");
|
|
12826
|
+
}
|
|
12827
|
+
if (cursor === "")
|
|
12828
|
+
throw new Error("--cursor requires a non-empty token.");
|
|
12829
|
+
return {
|
|
12830
|
+
name: getFlag(flags, "name"),
|
|
12831
|
+
createdBy: getFlag(flags, "createdBy"),
|
|
12832
|
+
createdByIds: parseCommaSeparatedIds(getFlag(flags, "createdByIds")),
|
|
12833
|
+
active: parseOptionalBoolFlag(flags, "active"),
|
|
12834
|
+
limit: parseCompanyLimit(getFlag(flags, "limit")),
|
|
12835
|
+
cursor,
|
|
12836
|
+
direction,
|
|
12837
|
+
sortBy: parseCompanySortBy(getFlag(flags, "sortBy")),
|
|
12838
|
+
sortDir: parseCompanySortDir(getFlag(flags, "sortDir"))
|
|
12839
|
+
};
|
|
12840
|
+
};
|
|
12841
|
+
var parseCompanyCountFlags = (flags) => {
|
|
12842
|
+
rejectCompanyPageFlags(flags, "count");
|
|
12843
|
+
for (const key of [
|
|
12844
|
+
"name",
|
|
12845
|
+
"createdBy",
|
|
12846
|
+
"createdByIds",
|
|
12847
|
+
"active",
|
|
12848
|
+
"limit",
|
|
12849
|
+
"cursor",
|
|
12850
|
+
"direction",
|
|
12851
|
+
"sortBy",
|
|
12852
|
+
"sortDir"
|
|
12853
|
+
]) {
|
|
12854
|
+
rejectBareFlag(flags, key);
|
|
12855
|
+
}
|
|
12856
|
+
if (flags.limit !== undefined || flags.cursor !== undefined || flags.direction !== undefined) {
|
|
12857
|
+
throw new Error("company count does not accept list pagination flags.");
|
|
12858
|
+
}
|
|
12859
|
+
if (flags.sortBy !== undefined || flags.sortDir !== undefined) {
|
|
12860
|
+
throw new Error("company count does not accept list sorting flags.");
|
|
12861
|
+
}
|
|
12862
|
+
return {
|
|
12863
|
+
name: getFlag(flags, "name"),
|
|
12864
|
+
createdBy: getFlag(flags, "createdBy"),
|
|
12865
|
+
createdByIds: parseCommaSeparatedIds(getFlag(flags, "createdByIds")),
|
|
12866
|
+
active: parseOptionalBoolFlag(flags, "active")
|
|
12867
|
+
};
|
|
12868
|
+
};
|
|
12869
|
+
var PROJECT_SORT_FIELDS = [
|
|
12870
|
+
"name",
|
|
12871
|
+
"createdAt",
|
|
12872
|
+
"status",
|
|
12873
|
+
"companyName",
|
|
12874
|
+
"wonAt"
|
|
12875
|
+
];
|
|
12876
|
+
var PROJECT_SORT_DIRECTIONS = ["asc", "desc"];
|
|
12877
|
+
var PROJECT_PAGE_FLAGS = [
|
|
12878
|
+
"page",
|
|
12879
|
+
"perPage",
|
|
12880
|
+
"pageSize",
|
|
12881
|
+
"page-size",
|
|
12882
|
+
"per-page",
|
|
12883
|
+
"page_size",
|
|
12884
|
+
"per_page"
|
|
12885
|
+
];
|
|
12886
|
+
var rejectProjectPageFlags = (flags, command) => {
|
|
12887
|
+
for (const key of PROJECT_PAGE_FLAGS) {
|
|
12888
|
+
if (flags[key] !== undefined) {
|
|
12889
|
+
throw new Error(`--${key} is not supported by project ${command}; use --limit and --cursor for list or project count for totals.`);
|
|
12890
|
+
}
|
|
12891
|
+
}
|
|
12892
|
+
};
|
|
12893
|
+
var parseProjectLimit = (value) => {
|
|
12894
|
+
if (value === undefined)
|
|
12895
|
+
return 20;
|
|
12896
|
+
const parsed = Number(String(value));
|
|
12897
|
+
if (!Number.isInteger(parsed) || parsed < 1 || parsed > 100) {
|
|
12898
|
+
throw new Error("--limit must be an integer from 1 to 100.");
|
|
12899
|
+
}
|
|
12900
|
+
return parsed;
|
|
12901
|
+
};
|
|
12902
|
+
var parseProjectSortBy = (value) => {
|
|
12903
|
+
if (value === undefined)
|
|
12904
|
+
return "createdAt";
|
|
12905
|
+
if (!PROJECT_SORT_FIELDS.includes(value)) {
|
|
12906
|
+
throw new Error(`Invalid --sortBy "${value}". Use one of: ${PROJECT_SORT_FIELDS.join(", ")}.`);
|
|
12907
|
+
}
|
|
12908
|
+
return value;
|
|
12909
|
+
};
|
|
12910
|
+
var parseProjectSortDir = (value) => {
|
|
12911
|
+
if (value === undefined)
|
|
12912
|
+
return "desc";
|
|
12913
|
+
if (!PROJECT_SORT_DIRECTIONS.includes(value)) {
|
|
12914
|
+
throw new Error(`Invalid --sortDir "${value}". Use one of: ${PROJECT_SORT_DIRECTIONS.join(", ")}.`);
|
|
12915
|
+
}
|
|
12916
|
+
return value;
|
|
12917
|
+
};
|
|
12918
|
+
var parseProjectWonWithinDays = (value) => {
|
|
11899
12919
|
if (value === undefined)
|
|
11900
12920
|
return;
|
|
11901
|
-
const parsed = Number
|
|
11902
|
-
if (!Number.
|
|
11903
|
-
throw new Error(
|
|
12921
|
+
const parsed = Number(value);
|
|
12922
|
+
if (!Number.isInteger(parsed) || parsed < 1 || parsed > 3650) {
|
|
12923
|
+
throw new Error("--wonWithinDays must be an integer from 1 to 3650.");
|
|
11904
12924
|
}
|
|
11905
12925
|
return parsed;
|
|
11906
|
-
}
|
|
12926
|
+
};
|
|
12927
|
+
var parseProjectDirection = (value) => {
|
|
12928
|
+
if (value === undefined)
|
|
12929
|
+
return "forward";
|
|
12930
|
+
if (value !== "forward" && value !== "backward") {
|
|
12931
|
+
throw new Error('--direction must be "forward" or "backward".');
|
|
12932
|
+
}
|
|
12933
|
+
return value;
|
|
12934
|
+
};
|
|
12935
|
+
var parseProjectListFlags = (flags) => {
|
|
12936
|
+
rejectProjectPageFlags(flags, "list");
|
|
12937
|
+
for (const key of [
|
|
12938
|
+
"companyId",
|
|
12939
|
+
"name",
|
|
12940
|
+
"status",
|
|
12941
|
+
"statuses",
|
|
12942
|
+
"active",
|
|
12943
|
+
"wonFrom",
|
|
12944
|
+
"wonTo",
|
|
12945
|
+
"wonWithinDays",
|
|
12946
|
+
"limit",
|
|
12947
|
+
"cursor",
|
|
12948
|
+
"direction",
|
|
12949
|
+
"sortBy",
|
|
12950
|
+
"sortDir"
|
|
12951
|
+
]) {
|
|
12952
|
+
rejectBareFlag(flags, key);
|
|
12953
|
+
}
|
|
12954
|
+
const cursor = getFlag(flags, "cursor");
|
|
12955
|
+
const direction = parseProjectDirection(getFlag(flags, "direction"));
|
|
12956
|
+
if (direction === "backward" && cursor === undefined) {
|
|
12957
|
+
throw new Error("--direction backward requires --cursor <token>.");
|
|
12958
|
+
}
|
|
12959
|
+
if (cursor === "")
|
|
12960
|
+
throw new Error("--cursor requires a non-empty token.");
|
|
12961
|
+
return {
|
|
12962
|
+
companyId: getFlag(flags, "companyId"),
|
|
12963
|
+
name: getFlag(flags, "name"),
|
|
12964
|
+
status: parseOptionalExtendedProjectStatus(getFlag(flags, "status")),
|
|
12965
|
+
statuses: parseCommaSeparatedProjectStatuses(getFlag(flags, "statuses")),
|
|
12966
|
+
active: parseOptionalBoolFlag(flags, "active"),
|
|
12967
|
+
wonFrom: parseOptionalIsoDateFlag(getFlag(flags, "wonFrom"), "--wonFrom"),
|
|
12968
|
+
wonTo: parseOptionalIsoDateFlag(getFlag(flags, "wonTo"), "--wonTo", {
|
|
12969
|
+
endOfDay: true
|
|
12970
|
+
}),
|
|
12971
|
+
wonWithinDays: parseProjectWonWithinDays(getFlag(flags, "wonWithinDays")),
|
|
12972
|
+
limit: parseProjectLimit(getFlag(flags, "limit")),
|
|
12973
|
+
cursor,
|
|
12974
|
+
direction,
|
|
12975
|
+
sortBy: parseProjectSortBy(getFlag(flags, "sortBy")),
|
|
12976
|
+
sortDir: parseProjectSortDir(getFlag(flags, "sortDir"))
|
|
12977
|
+
};
|
|
12978
|
+
};
|
|
12979
|
+
var parseProjectCountFlags = (flags) => {
|
|
12980
|
+
rejectProjectPageFlags(flags, "count");
|
|
12981
|
+
for (const key of [
|
|
12982
|
+
"companyId",
|
|
12983
|
+
"name",
|
|
12984
|
+
"status",
|
|
12985
|
+
"statuses",
|
|
12986
|
+
"active",
|
|
12987
|
+
"wonFrom",
|
|
12988
|
+
"wonTo",
|
|
12989
|
+
"wonWithinDays",
|
|
12990
|
+
"limit",
|
|
12991
|
+
"cursor",
|
|
12992
|
+
"direction",
|
|
12993
|
+
"sortBy",
|
|
12994
|
+
"sortDir"
|
|
12995
|
+
]) {
|
|
12996
|
+
rejectBareFlag(flags, key);
|
|
12997
|
+
}
|
|
12998
|
+
if (flags.limit !== undefined || flags.cursor !== undefined || flags.direction !== undefined) {
|
|
12999
|
+
throw new Error("project count does not accept list pagination flags.");
|
|
13000
|
+
}
|
|
13001
|
+
if (flags.sortBy !== undefined || flags.sortDir !== undefined) {
|
|
13002
|
+
throw new Error("project count does not accept list sorting flags.");
|
|
13003
|
+
}
|
|
13004
|
+
return {
|
|
13005
|
+
companyId: getFlag(flags, "companyId"),
|
|
13006
|
+
name: getFlag(flags, "name"),
|
|
13007
|
+
status: parseOptionalExtendedProjectStatus(getFlag(flags, "status")),
|
|
13008
|
+
statuses: parseCommaSeparatedProjectStatuses(getFlag(flags, "statuses")),
|
|
13009
|
+
active: parseOptionalBoolFlag(flags, "active"),
|
|
13010
|
+
wonFrom: parseOptionalIsoDateFlag(getFlag(flags, "wonFrom"), "--wonFrom"),
|
|
13011
|
+
wonTo: parseOptionalIsoDateFlag(getFlag(flags, "wonTo"), "--wonTo", {
|
|
13012
|
+
endOfDay: true
|
|
13013
|
+
}),
|
|
13014
|
+
wonWithinDays: parseProjectWonWithinDays(getFlag(flags, "wonWithinDays"))
|
|
13015
|
+
};
|
|
13016
|
+
};
|
|
11907
13017
|
function parseOptionalBoolFlag(flags, key) {
|
|
11908
13018
|
const v = flags[key];
|
|
11909
13019
|
if (v === undefined || v === true)
|
|
@@ -11954,28 +13064,90 @@ function parseCommercialRejectionProjectStatus(flags) {
|
|
|
11954
13064
|
throw new Error("--projectStatusOnCommercialRejection requires PITCH or LOST.");
|
|
11955
13065
|
}
|
|
11956
13066
|
const status = String(raw).toUpperCase();
|
|
11957
|
-
if (status ===
|
|
13067
|
+
if (status === ProjectStatus2.PITCH || status === ProjectStatus2.LOST) {
|
|
11958
13068
|
return status;
|
|
11959
13069
|
}
|
|
11960
13070
|
throw new Error("--projectStatusOnCommercialRejection must be PITCH or LOST.");
|
|
11961
13071
|
}
|
|
11962
|
-
|
|
13072
|
+
var rejectRetiredPageFlags = (flags) => {
|
|
13073
|
+
for (const key of PROJECT_PAGE_FLAGS) {
|
|
13074
|
+
if (flags[key] !== undefined)
|
|
13075
|
+
throw new Error(`--${key} is retired; use --limit/--cursor, or the matching count command for totals.`);
|
|
13076
|
+
}
|
|
13077
|
+
};
|
|
13078
|
+
var parseDetailFeedPage = (command, idLabel, positional, flags, maxLimit) => {
|
|
13079
|
+
const id = positional[0];
|
|
13080
|
+
if (!id)
|
|
13081
|
+
throw new Error(`${command} requires ${idLabel}`);
|
|
13082
|
+
rejectRetiredPageFlags(flags);
|
|
13083
|
+
for (const key of ["limit", "cursor"])
|
|
13084
|
+
rejectBareFlag(flags, key);
|
|
13085
|
+
if (flags.direction !== undefined)
|
|
13086
|
+
throw new Error(`${command} pages forward only; follow pageInfo.nextCursor with --cursor.`);
|
|
13087
|
+
const cursor = getFlag(flags, "cursor");
|
|
13088
|
+
if (cursor === "" || (cursor?.length ?? 0) > 8192)
|
|
13089
|
+
throw new Error("--cursor must be a non-empty opaque token of at most 8192 characters.");
|
|
13090
|
+
const limitFlag = getFlag(flags, "limit");
|
|
13091
|
+
const limit = limitFlag === undefined ? undefined : Number(limitFlag);
|
|
13092
|
+
if (limit !== undefined && (!Number.isInteger(limit) || limit < 1 || limit > maxLimit))
|
|
13093
|
+
throw new Error(`--limit must be an integer from 1 to ${maxLimit}.`);
|
|
13094
|
+
return { id, limit, cursor };
|
|
13095
|
+
};
|
|
13096
|
+
var parseBillFilterFlags = (flags) => {
|
|
11963
13097
|
const statusRaw = getFlag(flags, "status");
|
|
11964
13098
|
const createdByIdsRaw = getFlag(flags, "createdByIds");
|
|
11965
13099
|
const searchRaw = getFlag(flags, "search");
|
|
11966
|
-
const sortByRaw = getFlag(flags, "sortBy");
|
|
11967
|
-
const sortDirRaw = getFlag(flags, "sortDir");
|
|
11968
13100
|
return {
|
|
11969
13101
|
projectId: getFlag(flags, "projectId"),
|
|
11970
13102
|
budgetId: getFlag(flags, "budgetId"),
|
|
11971
13103
|
statuses: parseCommaSeparatedBillStatuses(statusRaw !== undefined ? String(statusRaw) : undefined),
|
|
11972
13104
|
search: searchRaw !== undefined ? String(searchRaw) : undefined,
|
|
11973
13105
|
isClaimable: parseOptionalBoolFlag(flags, "isClaimable"),
|
|
11974
|
-
createdByIds: parseCommaSeparatedIds(createdByIdsRaw !== undefined ? String(createdByIdsRaw) : undefined)
|
|
13106
|
+
createdByIds: parseCommaSeparatedIds(createdByIdsRaw !== undefined ? String(createdByIdsRaw) : undefined)
|
|
13107
|
+
};
|
|
13108
|
+
};
|
|
13109
|
+
var parseQuotationFilterFlags = (flags) => {
|
|
13110
|
+
const createdByRaw = getFlag(flags, "createdBy") ?? getFlag(flags, "requesterIds");
|
|
13111
|
+
const searchRaw = getFlag(flags, "search");
|
|
13112
|
+
return {
|
|
13113
|
+
projectId: getFlag(flags, "projectId"),
|
|
13114
|
+
budgetId: getFlag(flags, "budgetId"),
|
|
13115
|
+
supplierId: getFlag(flags, "supplierId"),
|
|
13116
|
+
status: parseCommaSeparatedQuotationStatuses(getFlag(flags, "status")),
|
|
13117
|
+
createdBy: parseCommaSeparatedIds(createdByRaw),
|
|
13118
|
+
search: searchRaw !== undefined ? String(searchRaw).trim() || undefined : undefined
|
|
13119
|
+
};
|
|
13120
|
+
};
|
|
13121
|
+
function parseListBillsFlags(flags) {
|
|
13122
|
+
rejectRetiredPageFlags(flags);
|
|
13123
|
+
for (const key of ["limit", "cursor", "direction", "sortBy", "sortDir"])
|
|
13124
|
+
rejectBareFlag(flags, key);
|
|
13125
|
+
const sortByRaw = getFlag(flags, "sortBy");
|
|
13126
|
+
const sortDirRaw = getFlag(flags, "sortDir");
|
|
13127
|
+
const cursor = getFlag(flags, "cursor");
|
|
13128
|
+
if (cursor === "" || (cursor?.length ?? 0) > 8192)
|
|
13129
|
+
throw new Error("--cursor must be a non-empty opaque token of at most 8192 characters.");
|
|
13130
|
+
const direction = parseProjectDirection(getFlag(flags, "direction"));
|
|
13131
|
+
if (direction === "backward" && !cursor)
|
|
13132
|
+
throw new Error("--direction backward requires --cursor <token>.");
|
|
13133
|
+
return {
|
|
13134
|
+
...parseBillFilterFlags(flags),
|
|
11975
13135
|
sortBy: parseOptionalBillListSortBy(sortByRaw !== undefined ? String(sortByRaw) : undefined),
|
|
11976
13136
|
sortDir: parseOptionalBillListSortDir(sortDirRaw !== undefined ? String(sortDirRaw) : undefined),
|
|
11977
|
-
|
|
11978
|
-
|
|
13137
|
+
limit: parseProjectLimit(getFlag(flags, "limit")),
|
|
13138
|
+
cursor,
|
|
13139
|
+
direction
|
|
13140
|
+
};
|
|
13141
|
+
}
|
|
13142
|
+
function parseCountBillsFlags(flags) {
|
|
13143
|
+
rejectRetiredPageFlags(flags);
|
|
13144
|
+
for (const key of ["limit", "cursor", "direction", "sortBy", "sortDir"]) {
|
|
13145
|
+
if (flags[key] !== undefined)
|
|
13146
|
+
throw new Error(`bill count does not accept --${key}; totals use filters only.`);
|
|
13147
|
+
}
|
|
13148
|
+
return {
|
|
13149
|
+
...parseBillFilterFlags(flags),
|
|
13150
|
+
includeMetrics: parseOptionalBoolFlag(flags, "includeMetrics") ?? false
|
|
11979
13151
|
};
|
|
11980
13152
|
}
|
|
11981
13153
|
var SUPPLIER_SORT_FIELDS = [
|
|
@@ -11996,25 +13168,89 @@ function parseOptionalSupplierSortBy(raw) {
|
|
|
11996
13168
|
}
|
|
11997
13169
|
return raw;
|
|
11998
13170
|
}
|
|
11999
|
-
|
|
12000
|
-
const
|
|
12001
|
-
|
|
12002
|
-
|
|
12003
|
-
|
|
12004
|
-
|
|
12005
|
-
|
|
13171
|
+
var parseSupplierFilters = (flags) => {
|
|
13172
|
+
for (const key of [
|
|
13173
|
+
"name",
|
|
13174
|
+
"createdBy",
|
|
13175
|
+
"gstRegistered",
|
|
13176
|
+
"status",
|
|
13177
|
+
"supplierTags",
|
|
13178
|
+
"active"
|
|
13179
|
+
])
|
|
13180
|
+
rejectBareFlag(flags, key);
|
|
12006
13181
|
return {
|
|
12007
13182
|
name: getFlag(flags, "name"),
|
|
12008
|
-
|
|
12009
|
-
|
|
12010
|
-
|
|
12011
|
-
|
|
12012
|
-
|
|
12013
|
-
status: parseCommaSeparatedSupplierStatuses(statusRaw !== undefined ? String(statusRaw) : undefined),
|
|
12014
|
-
supplierTags: parseCommaSeparatedIds(supplierTagsRaw !== undefined ? String(supplierTagsRaw) : undefined),
|
|
12015
|
-
active: parseOptionalBoolFlag(flags, "active")
|
|
13183
|
+
createdBy: parseCommaSeparatedIds(getFlag(flags, "createdBy")),
|
|
13184
|
+
gstRegistered: parseOptionalBoolFlag(flags, "gstRegistered") ?? null,
|
|
13185
|
+
status: parseCommaSeparatedSupplierStatuses(getFlag(flags, "status")),
|
|
13186
|
+
supplierTags: parseCommaSeparatedIds(getFlag(flags, "supplierTags")),
|
|
13187
|
+
active: parseOptionalBoolFlag(flags, "active") ?? true
|
|
12016
13188
|
};
|
|
12017
|
-
}
|
|
13189
|
+
};
|
|
13190
|
+
var rejectSupplierPageFlags = (flags) => {
|
|
13191
|
+
for (const key of PROJECT_PAGE_FLAGS) {
|
|
13192
|
+
if (flags[key] !== undefined)
|
|
13193
|
+
throw new Error(`--${key} is retired for suppliers; use --limit/--cursor or supplier count for totals.`);
|
|
13194
|
+
}
|
|
13195
|
+
};
|
|
13196
|
+
var parseListSuppliersFlags = (flags) => {
|
|
13197
|
+
rejectSupplierPageFlags(flags);
|
|
13198
|
+
for (const key of [
|
|
13199
|
+
"limit",
|
|
13200
|
+
"cursor",
|
|
13201
|
+
"direction",
|
|
13202
|
+
"sort",
|
|
13203
|
+
"sortBy",
|
|
13204
|
+
"sortDir"
|
|
13205
|
+
])
|
|
13206
|
+
rejectBareFlag(flags, key);
|
|
13207
|
+
const limit = getFlag(flags, "limit") === undefined ? 10 : parseProjectLimit(getFlag(flags, "limit"));
|
|
13208
|
+
const cursor = getFlag(flags, "cursor");
|
|
13209
|
+
if (cursor === "" || (cursor?.length ?? 0) > 8192)
|
|
13210
|
+
throw new Error("--cursor must be a non-empty opaque token of at most 8192 characters.");
|
|
13211
|
+
const direction = parseProjectDirection(getFlag(flags, "direction"));
|
|
13212
|
+
if (direction === "backward" && !cursor)
|
|
13213
|
+
throw new Error("--direction backward requires --cursor <token>.");
|
|
13214
|
+
const sortRaw = getFlag(flags, "sort");
|
|
13215
|
+
let sort;
|
|
13216
|
+
if (sortRaw !== undefined) {
|
|
13217
|
+
if (flags.sortBy !== undefined || flags.sortDir !== undefined)
|
|
13218
|
+
throw new Error("Use --sort or --sortBy/--sortDir, not both.");
|
|
13219
|
+
const parsed = parseJsonFlag(sortRaw, "--sort");
|
|
13220
|
+
if (!Array.isArray(parsed) || parsed.length > 8)
|
|
13221
|
+
throw new Error("--sort must be a JSON array of at most eight {id, desc} entries.");
|
|
13222
|
+
sort = parsed.map((item) => {
|
|
13223
|
+
if (typeof item !== "object" || item === null || !("id" in item) || !("desc" in item) || typeof item.id !== "string" || typeof item.desc !== "boolean" || Object.keys(item).some((key) => key !== "id" && key !== "desc"))
|
|
13224
|
+
throw new Error("Invalid --sort entry; use {id, desc}.");
|
|
13225
|
+
const id = parseOptionalSupplierSortBy(item.id);
|
|
13226
|
+
if (!id)
|
|
13227
|
+
throw new Error("Invalid --sort field.");
|
|
13228
|
+
return { id, desc: item.desc };
|
|
13229
|
+
});
|
|
13230
|
+
} else {
|
|
13231
|
+
const sortBy = parseOptionalSupplierSortBy(getFlag(flags, "sortBy"));
|
|
13232
|
+
const sortDir = parseOptionalBillListSortDir(getFlag(flags, "sortDir"));
|
|
13233
|
+
sort = [
|
|
13234
|
+
{ id: sortBy ?? "createdAt", desc: (sortDir ?? "desc") === "desc" }
|
|
13235
|
+
];
|
|
13236
|
+
}
|
|
13237
|
+
return { ...parseSupplierFilters(flags), limit, cursor, direction, sort };
|
|
13238
|
+
};
|
|
13239
|
+
var parseCountSuppliersFlags = (flags) => {
|
|
13240
|
+
rejectSupplierPageFlags(flags);
|
|
13241
|
+
for (const key of [
|
|
13242
|
+
"limit",
|
|
13243
|
+
"cursor",
|
|
13244
|
+
"direction",
|
|
13245
|
+
"sort",
|
|
13246
|
+
"sortBy",
|
|
13247
|
+
"sortDir"
|
|
13248
|
+
]) {
|
|
13249
|
+
if (flags[key] !== undefined)
|
|
13250
|
+
throw new Error(`supplier count does not accept --${key}; totals use filters only.`);
|
|
13251
|
+
}
|
|
13252
|
+
return parseSupplierFilters(flags);
|
|
13253
|
+
};
|
|
12018
13254
|
function parseDashboardQueryFlags(flags) {
|
|
12019
13255
|
const roleRaw = getFlag(flags, "role");
|
|
12020
13256
|
const timeFrameRaw = getFlag(flags, "timeFrame");
|
|
@@ -12049,7 +13285,8 @@ pending-approver assignment. On FORBIDDEN, stop and report the identity, role,
|
|
|
12049
13285
|
command, and target; do not switch keys or try a lower-level procedure.
|
|
12050
13286
|
|
|
12051
13287
|
Sensitive workflow changes: approval decisions/requests, entity status updates,
|
|
12052
|
-
estimate emails, customer invoices, integration retries
|
|
13288
|
+
estimate emails, customer invoices, integration retries and QuickBooks outcome
|
|
13289
|
+
verification, mark-budget-won,
|
|
12053
13290
|
submit-quotation, and supplier approval request side effects require an
|
|
12054
13291
|
interactive CONFIRM prompt and abort in non-interactive shells.
|
|
12055
13292
|
AI agents must inspect the entity first, summarize the exact entity, target
|
|
@@ -12060,15 +13297,20 @@ Budget mutations return a conflict while an estimate email is queued,
|
|
|
12060
13297
|
processing, or awaiting provider reconciliation.
|
|
12061
13298
|
|
|
12062
13299
|
Budgets
|
|
12063
|
-
list-budgets [--projectId] [--name] [--status CSV] [--createdBy] [--dateFrom] [--dateTo] [--sortBy] [--sortDir] [--
|
|
13300
|
+
list-budgets [--projectId] [--name] [--status CSV] [--createdBy] [--dateFrom] [--dateTo] [--sortBy lastActivityAt|createdAt|status|budget|date|createdBy] [--sortDir] [--limit 1-100] [--cursor <token>] [--direction forward|backward] [--summary]
|
|
13301
|
+
Returns { items, pageInfo }; follow nextCursor/previousCursor with the same filters and sort. --page/--perPage are rejected.
|
|
13302
|
+
count-budgets [same filter flags as list-budgets] totalCount plus status and active facets (each ignores its own filter)
|
|
12064
13303
|
get-budget <id> Budget + line items
|
|
12065
13304
|
get-budget-items <id> Line items only
|
|
12066
13305
|
get-budget-details <id> Full detail (margins, suppliers, etc.)
|
|
12067
|
-
get-budget-categories
|
|
12068
|
-
|
|
13306
|
+
get-budget-categories [--q] [--limit 1-100] [--cursor <token>]
|
|
13307
|
+
Active categories, name A\u2013Z. Returns { items, pageInfo }; follow nextCursor with the same --q.
|
|
13308
|
+
get-budget-versions <budgetId> [--limit <1-50>] [--cursor <token> | --all]
|
|
12069
13309
|
rename-budget-version <versionId> --name <text>
|
|
12070
13310
|
restore-budget-version <versionId> Replace current budget data and return it to DRAFT.
|
|
12071
13311
|
update-budget-status <id> <status> [--projectManagerId <id>] [--markProjectWon true|false] [--projectStatusOnCommercialRejection PITCH|LOST]
|
|
13312
|
+
APPROVED requires a current Lead/Admin role, regardless of budget management permissions. Ordinary users must request approval.
|
|
13313
|
+
Material edits and generic status changes invalidate older pending budget requests; decide only a fresh request for the content reviewed.
|
|
12072
13314
|
Budget-changing commands require interactive "yes" confirmation when the current budget is ESTIMATE_CREATED, ESTIMATE_SENT, ESTIMATE_ACCEPTED, ESTIMATE_REJECTED, or ESTIMATE_CLOSED.
|
|
12073
13315
|
ESTIMATE_ACCEPTED requires win proof, auto-marks PITCH or LOST projects WON, requires --projectManagerId when the project has no PM, and auto-creates the Asana project/section when enabled.
|
|
12074
13316
|
ESTIMATE_REJECTED requires --projectStatusOnCommercialRejection when rejecting the only accepted/closed budget on a commercial project.
|
|
@@ -12078,7 +13320,7 @@ Budgets
|
|
|
12078
13320
|
update-budget --payload '<json>' (budget.updateBudget; must include id)
|
|
12079
13321
|
delete-budget <budgetId>
|
|
12080
13322
|
create-budget-approval <budgetId> (also queues approval request emails)
|
|
12081
|
-
create-estimate <budgetId> (
|
|
13323
|
+
create-estimate <budgetId> (queues QuickBooks estimate creation; budget is read-only until it settles; supports preflight updates)
|
|
12082
13324
|
send-estimate-to-contact-person --payload '<json>' Send using the web contact-person workflow; payload includes recipient fields plus HTML content/signature.
|
|
12083
13325
|
add-budget-items --budgetId --items '[{"itemId":"\u2026","quantity":1,"markup":30},\u2026]'
|
|
12084
13326
|
update-budget-item --id <budgetItemId> [--description plain-text] [--note plain-text] [--quantity] [--markup] [--cost] [--unitPrice] [--isFreeOfCharge true|false] [--gstInclusive true|false] [--gstOutOfScope true|false]
|
|
@@ -12086,7 +13328,7 @@ Budgets
|
|
|
12086
13328
|
replace-budget-item --budgetItemId <id> --replacementItemId <activeCatalogueItemId>
|
|
12087
13329
|
approve-unavailable-item-exception --budgetItemId <id> --reason <text> Lead/Admin only; reason must be 5-1000 characters.
|
|
12088
13330
|
reorder-budget-items <budgetId> --itemIds <csv>
|
|
12089
|
-
update-budget-item-supplier --budgetItemId --supplierId
|
|
13331
|
+
update-budget-item-supplier --budgetItemId --supplierId Material supplier/GST edit: supersedes pending approvals and applies the standard budget reset policy; unchanged supplier is a no-op.
|
|
12090
13332
|
create-budget-category --name <text>
|
|
12091
13333
|
update-budget-category --id --name
|
|
12092
13334
|
delete-budget-category <id>
|
|
@@ -12100,8 +13342,11 @@ Budgets
|
|
|
12100
13342
|
upload-budget-attachment <budgetId> <filePath> Presigned S3 upload + confirm
|
|
12101
13343
|
|
|
12102
13344
|
Bills
|
|
12103
|
-
list-bills [--projectId] [--budgetId] [--status CSV] [--search <text>] [--isClaimable true|false] [--createdByIds <csv>] [--sortBy createdAt|amount|status] [--sortDir asc|desc] [--
|
|
13345
|
+
list-bills [--projectId] [--budgetId] [--status CSV] [--search <text>] [--isClaimable true|false] [--createdByIds <csv>] [--sortBy createdAt|amount|status] [--sortDir asc|desc] [--limit 1-100] [--cursor <token>] [--direction forward|backward]
|
|
13346
|
+
Returns { items, pageInfo }; pass nextCursor with --direction forward or previousCursor with --direction backward, keeping the same filters and sort. --page/--pageSize/--perPage are rejected.
|
|
12104
13347
|
list-claims same flags as list-bills; only reimbursable claims (ignores --isClaimable)
|
|
13348
|
+
count-bills [--projectId] [--budgetId] [--status CSV] [--search <text>] [--isClaimable true|false] [--createdByIds <csv>] [--includeMetrics true|false] totalCount, status facets (ignore --status) and optional amount metrics; no pagination/sort flags
|
|
13349
|
+
count-claims same flags as count-bills; only reimbursable claims
|
|
12105
13350
|
Both lists return summaries; use get-bill-details <billId> for full detail.
|
|
12106
13351
|
isClaimable differentiates the shared bill/claim records: false = bill, true = claim.
|
|
12107
13352
|
Create supplier bills from approved quotations from the same supplier and project. Use quotationAllocations plus lineAmounts when quotations split one bill line. Eligible exemptions require explicit --quotation-exempt intent; claims do not consume or link quotations.
|
|
@@ -12112,7 +13357,7 @@ Bills
|
|
|
12112
13357
|
validate-bill-selection --payload '<json>' [--quotationIds <csv> | --quotationId <id>] Validate an approved supplier and approved quotation coverage for each supplier-bill line. --quotationId is legacy single-quotation syntax.
|
|
12113
13358
|
link-bill-quotations <billId> (--payload '<json>' | --quotationIds <csv>) Admin-only source-link repair; payload.quotationAllocations supports same-line splits.
|
|
12114
13359
|
stage-bill-attachment <projectId> <filePath...> [--file <path>] [--files <csv>] Upload files before create-bill; returns attachment JSON for attachments/paymentProofAttachments
|
|
12115
|
-
cleanup-staged-bill-attachments <projectId> --keys <csv>
|
|
13360
|
+
cleanup-staged-bill-attachments <projectId> --keys <csv> Queue cleanup of unattached staged uploads; returns operation IDs.
|
|
12116
13361
|
update-bill --payload '<json>' (bill.update; must include id)
|
|
12117
13362
|
update-bill-payment-evidence --payload '<json>' Replace paymentReference/paymentProofAttachments for an already-paid bill.
|
|
12118
13363
|
delete-bill <billId>
|
|
@@ -12123,23 +13368,29 @@ Bills
|
|
|
12123
13368
|
patch-bill-payment <billId> [--paymentTrackingUrl] [--paymentReference] [--quickbooksBillId] [--paymentDate <ISO>]
|
|
12124
13369
|
Clear a field: --clearPaymentTrackingUrl true | --clearPaymentReference true | --clearQuickbooksBillId true | --clearPaymentDate true
|
|
12125
13370
|
patch-bill-invoice-number <billId> <invoiceNumber>
|
|
12126
|
-
get-bill-attachments <billId>
|
|
13371
|
+
get-bill-attachments <billId> [--limit 1-50] [--cursor <token>]
|
|
13372
|
+
Newest first. Returns { items, pageInfo }; follow nextCursor.
|
|
12127
13373
|
upload-bill-attachment <billId> <filePath...> [--file <path>] [--files <csv>] Attach invoice/supporting files as BILL attachments to any bill status, including PAID bills
|
|
12128
13374
|
attach-bill-payment-receipt <billId> <filePath...> [--file <path>] [--files <csv>] Attach Wise/payment-proof PDFs as BILL_PAYMENT_PROOF attachments
|
|
12129
13375
|
attach-bill-documents <billId> [--invoice <path>] [--invoices <csv>] [--paymentProof|--payment-proof|--proof <path>] [--paymentProofs|--payment-proofs|--proofs <csv>] Attach invoice and/or payment proof files with separate BB attachment types
|
|
12130
|
-
get-bill-details <billId>
|
|
13376
|
+
get-bill-details <billId> Bill summary as shown in the web app (status, amounts, people, payment, line totals)
|
|
13377
|
+
get-bill-line-items <billId> [--limit 1-100] [--cursor <token>] Line items with budget-item/quotation detail; { items, pageInfo }
|
|
13378
|
+
get-bill-approvals <billId> [--limit 1-50] [--cursor <token>] Approval requests with approver/requester/responder; { items, pageInfo }
|
|
13379
|
+
get-bill-payment <billId> Payment status, reference, date, tracking URL, QuickBooks link and external payment
|
|
12131
13380
|
|
|
12132
13381
|
Quotations
|
|
12133
|
-
list-quotations [--projectId] [--budgetId] [--supplierId] [--status CSV] [--createdBy CSV] [--search] [--
|
|
12134
|
-
|
|
12135
|
-
|
|
13382
|
+
list-quotations [--projectId] [--budgetId] [--supplierId] [--status CSV] [--createdBy CSV] [--search] [--limit 1-100] [--cursor <token>] [--direction forward|backward]
|
|
13383
|
+
Newest first; returns { items, pageInfo }. Follow nextCursor/previousCursor with the same filters. --page/--pageSize/--perPage are rejected; --requesterIds remains an alias for --createdBy.
|
|
13384
|
+
count-quotations [--projectId] [--budgetId] [--supplierId] [--status CSV] [--createdBy CSV] [--search] [--includeMetrics true|false] totalCount, status facets (ignore --status) and optional amount metrics
|
|
13385
|
+
get-quotation <quotationId> Quotation as shown in the web app (status, amounts, people, line totals, files, approvals)
|
|
13386
|
+
get-quotation-line-items <quotationId> [--limit 1-100] [--cursor <token>] Line items with budget-item detail; { items, pageInfo }
|
|
12136
13387
|
upload-quotation-attachment <projectId> <filePath> Upload one PDF, JPEG, or PNG up to 20MB; returns attachment JSON for a quotation payload.
|
|
12137
|
-
cleanup-staged-quotation-attachments <projectId> --keys <csv>
|
|
13388
|
+
cleanup-staged-quotation-attachments <projectId> --keys <csv> Queue cleanup of unattached quotation uploads; returns operation IDs.
|
|
12138
13389
|
create-quotation --payload '<json>' (quotation.createDraft; requires amountWithoutGst, gstAmount, and lineAmounts [{budgetItemId, amount}] for multiple budgetItemIds; amounts before GST must sum to amountWithoutGst)
|
|
12139
13390
|
update-quotation --payload '<json>' Update a DRAFT or REJECTED quotation; same allocation payload plus id; use lineAmounts [{budgetItemId, amount}] for every selected item.
|
|
12140
13391
|
delete-quotation <quotationId>
|
|
12141
13392
|
submit-quotation <quotationId> [--overBudgetOverrideReason <text>]
|
|
12142
|
-
approve-quotation <quotationId> [--overBudgetOverrideReason <text>]
|
|
13393
|
+
approve-quotation <quotationId> [--overBudgetOverrideReason <text>] (assigned pending request/current Admin; concurrent revision or allocation changes conflict)
|
|
12143
13394
|
reject-quotation <quotationId> --reason <text>
|
|
12144
13395
|
download-quotation-pdf <quotationId> [original|staff|final]
|
|
12145
13396
|
|
|
@@ -12148,9 +13399,15 @@ Customer invoices
|
|
|
12148
13399
|
list-eligible-customer-invoice-budgets <projectId> Accepted budgets that are ready and still have invoice coverage remaining, including estimate total, invoiced/remaining percentages, and available amount.
|
|
12149
13400
|
preview-customer-invoice-amount <budgetId> <percentage-of-estimate> Preview amount before GST, GST, and total for a percentage of the original estimate. The percentage cannot exceed the budget's remaining coverage.
|
|
12150
13401
|
list-available-qbo-customer-invoices <budgetId> List unlinked QuickBooks invoices available for this accepted or closed estimate before previewing and importing one.
|
|
12151
|
-
list-customer-invoices [budgetId] [--projectId <id>] [--companyIds CSV] [--projectIds CSV] [--budgetIds CSV] [--createdByIds CSV] [--status CSV] [--search] [--sortBy createdAt|status|totalInvoiceAmount|approvalExpiresAt] [--sortDir asc|desc] [--
|
|
13402
|
+
list-customer-invoices [budgetId] [--projectId <id>] [--companyIds CSV] [--projectIds CSV] [--budgetIds CSV] [--createdByIds CSV] [--status CSV] [--search] [--sortBy createdAt|status|totalInvoiceAmount|approvalExpiresAt] [--sortDir asc|desc] [--limit 1-100] [--cursor <token>] [--direction forward|backward]
|
|
13403
|
+
Returns { items, pageInfo }; follow nextCursor/previousCursor with the same filters and sort. --page/--perPage are rejected.
|
|
12152
13404
|
No scope flag lists invoices globally. --projectId uses the project scope. A positional budgetId is a backward-compatible shortcut for --budgetIds.
|
|
12153
|
-
|
|
13405
|
+
count-customer-invoices [budgetId] [same filter flags as list-customer-invoices] totalCount, lifecycle status facets (ignore --status) and amount metrics; no paging or sort flags
|
|
13406
|
+
get-customer-invoice <batchId> Batch as shown in the web app: status, totals, people, approvals and invoice summaries
|
|
13407
|
+
get-customer-invoice-invoices <batchId> Invoices with QuickBooks identity, dates and sync state
|
|
13408
|
+
get-customer-invoice-lines <invoiceId> [--limit 1-100] [--cursor <token>] One invoice's lines; { items, pageInfo }
|
|
13409
|
+
get-customer-invoice-approvals <batchId> [--limit 1-50] [--cursor <token>] Approval requests with approver/requester/responder; { items, pageInfo }
|
|
13410
|
+
get-customer-invoice-history <batchId> [--limit 1-100] [--cursor <token>] Status history; { items, pageInfo }
|
|
12154
13411
|
get-customer-invoice-email-context <batchId> Contact, required CC, budget, and project context for composing an invoice email.
|
|
12155
13412
|
preview-qbo-customer-invoice <budgetId> <qboInvoiceId> Preview an invoice selected from list-available-qbo-customer-invoices; works on accepted/closed estimates.
|
|
12156
13413
|
import-qbo-customer-invoice <budgetId> <qboInvoiceId> --token <previewToken> Confirm the reviewed BB-only link; requires --allow-state-change --allow-financial-write in automation.
|
|
@@ -12174,25 +13431,33 @@ Approvals
|
|
|
12174
13431
|
reject-supplier <supplierId> --reason <text> (also sends requester reply email)
|
|
12175
13432
|
|
|
12176
13433
|
Companies & projects
|
|
12177
|
-
list-companies [--name] [--createdBy] [--active true|false] [--
|
|
12178
|
-
|
|
13434
|
+
list-companies [--name] [--createdBy] [--createdByIds CSV] [--active true|false] [--sortBy name|createdAt] [--sortDir asc|desc] [--limit 1-100] [--cursor] [--direction forward|backward]
|
|
13435
|
+
Returns { items, pageInfo }; pass nextCursor with direction forward or previousCursor with direction backward. Omit --cursor to restart.
|
|
13436
|
+
count-companies [--name] [--createdBy] [--createdByIds CSV] [--active true|false]
|
|
13437
|
+
Returns independent { totalCount, counts: { active: { true, false } } }; no pagination or sorting flags.
|
|
12179
13438
|
get-company <id>
|
|
12180
|
-
search-existing-companies --query <name> [--
|
|
13439
|
+
search-existing-companies --query <name> [--limit 1-50] [--cursor <token>] (BB + QuickBooks, read-only; follow pageInfo.nextCursor)
|
|
12181
13440
|
use-existing-company --companyId <bbId> and/or --quickbooksId <qboId> [--website <url>] [--confirmDistinct true]
|
|
12182
13441
|
Supply both IDs to explicitly connect existing records with different names.
|
|
12183
13442
|
Reuses both records, creating only the missing counterpart. Website is needed only for a QBO import without one.
|
|
12184
13443
|
create-company --name --website <url> [--confirmDistinct true]
|
|
12185
13444
|
Exact existing companies are reused. Similar names require explicit separate-entity confirmation.
|
|
12186
|
-
update-company --payload '<json>' (
|
|
13445
|
+
update-company --payload '<json>' (saves BB fields; returns queued QBO operation ID, not completion)
|
|
13446
|
+
get-company-quickbooks-sync-status <companyId> (saved status only; no provider call or polling)
|
|
12187
13447
|
delete-company <id>
|
|
12188
|
-
list-projects [--companyId] [--name] [--status] [--active true|false] [--
|
|
12189
|
-
|
|
12190
|
-
|
|
13448
|
+
list-projects [--companyId] [--name] [--status|--statuses CSV] [--active true|false] [--wonFrom ISO] [--wonTo ISO] [--wonWithinDays N] [--limit 1-100] [--cursor] [--direction forward|backward] [--sortBy name|createdAt|status|companyName|wonAt] [--sortDir asc|desc]
|
|
13449
|
+
Returns { items, pageInfo }; pass nextCursor with direction forward or previousCursor with direction backward. Legacy --page/--perPage are rejected.
|
|
13450
|
+
--sortBy wonAt orders by when the project was marked WON (unwon projects last). Each project includes wonAt, wonBy { id, name } and wonAtEstimated (true for backfilled dates).
|
|
13451
|
+
count-projects [--companyId] [--name] [--status|--statuses CSV] [--active true|false] [--wonFrom ISO] [--wonTo ISO] [--wonWithinDays N]
|
|
13452
|
+
Returns independent { totalCount, counts: { status, active: { true, false } } }; no pagination or sorting flags.
|
|
13453
|
+
list-project-hubs [--q] [--status CSV] [--sortBy startDate|name|companyName|status] [--sortDir asc|desc] [--limit 1-100] [--cursor <token>] [--direction forward|backward]
|
|
13454
|
+
Returns { items, pageInfo }; follow nextCursor/previousCursor with the same filters and sort. --page/--perPage are rejected.
|
|
13455
|
+
count-project-hubs [--q] [--status CSV] totalCount plus status facet
|
|
12191
13456
|
List active projects that have a Project Hub integration.
|
|
12192
13457
|
get-project <id>
|
|
12193
13458
|
Budget overview totalRevenue includes Estimate Accepted and Estimate Closed budgets only.
|
|
12194
13459
|
create-project --name --companyId --contactPersonId --insideSalesId --businessDevelopmentId --venue --startDate <ISO> [--projectManagerId <userId>] [--asanaTaskId] [--asanaSearch <text>] [--slackChannelId --slackChannelUrl --slackChannelName] [--pax] [--endDate <ISO>] [--description]
|
|
12195
|
-
update-project --payload '<json>' (project.updateProject; warns before estimate-affecting changes reject linked estimates; optional projectManagerId and requestQboAccountantNotification)
|
|
13460
|
+
update-project --payload '<json>' (project.updateProject; warns before estimate-affecting changes reject linked estimates; a companyId change (with a contactPersonId from that company) does not itself reject estimates or touch invoices, but date/pax/venue changes in the same save still do; optional projectManagerId and requestQboAccountantNotification)
|
|
12196
13461
|
delete-project <id>
|
|
12197
13462
|
check-project-reconciliation <id> Run the same live reconciliation review as the web app without changing status.
|
|
12198
13463
|
reconcile-project <id> Rerun all checks transactionally and mark an eligible WON project RECONCILED.
|
|
@@ -12209,9 +13474,10 @@ Contacts
|
|
|
12209
13474
|
update-contact-person --payload '<json>' (contactPerson.updateContactPerson; must include id)
|
|
12210
13475
|
|
|
12211
13476
|
Suppliers & items
|
|
12212
|
-
list-suppliers [--name] [--
|
|
12213
|
-
|
|
12214
|
-
|
|
13477
|
+
list-suppliers [--name] [--limit 1-100] [--cursor <token>] [--direction forward|backward] [--sortBy createdAt|updatedAt|name|email|phone|gstRegistered|status|active] [--sortDir asc|desc | --sort JSON] [--createdBy <csv>] [--gstRegistered true|false] [--status CSV] [--supplierTags <csv>] [--active true|false]
|
|
13478
|
+
count-suppliers [--name] [--createdBy <csv>] [--gstRegistered true|false] [--status CSV] [--supplierTags <csv>] [--active true|false] (independent totals/facets; no pagination/sort flags)
|
|
13479
|
+
Defaults: --active true, --limit 10, --sortBy createdAt, --sortDir desc (same as the web list); pass --active false for archived suppliers.
|
|
13480
|
+
create-supplier --payload '<json>' (supplier.createSupplier; archived-name recreation is Admin-only; auto-requests approval + emails when status is PENDING_APPROVAL)
|
|
12215
13481
|
update-supplier --payload '<json>' (authenticated; normal-user edits require server-enforced approval)
|
|
12216
13482
|
delete-suppliers --ids <csv> (supplier.deleteSuppliers; admin; archives/deactivates supplier items)
|
|
12217
13483
|
reactivate-suppliers --ids <csv> (supplier.reactivateSuppliers; admin; reactivates supplier items)
|
|
@@ -12224,20 +13490,29 @@ Suppliers & items
|
|
|
12224
13490
|
archive-items --ids <csv> (item.archiveItems; Budget Builder only; max 100; users can archive their own items, leads/admins any item; open estimates retain snapshot lines and require resolution before send/acceptance)
|
|
12225
13491
|
delete-item <id> (item.deleteItem; admin; archives in Budget Builder and makes the item inactive in QuickBooks; blocked while used by an open estimate)
|
|
12226
13492
|
get-supplier-details <supplierId>
|
|
12227
|
-
get-supplier-analytics [--name] [--
|
|
12228
|
-
|
|
13493
|
+
get-supplier-analytics [--name] [--status CSV] [--gstRegistered true|false] [--createdBy <text>] [--timeFrame ALL|LAST_YEAR|LAST_6_MONTHS|LAST_3_MONTHS|CUSTOM] [--startDate <ISO> --endDate <ISO>] [--sortBy name|gstRegistered|status|phone|email|updatedAt|createdAt] [--sortDir asc|desc] [--limit 1-100] [--cursor <token>] [--direction forward|backward]
|
|
13494
|
+
Admin. Returns { items, pageInfo }; follow nextCursor/previousCursor with the same filters and sort. --page/--perPage are rejected.
|
|
13495
|
+
count-supplier-analytics [--name] [--status] [--gstRegistered] [--createdBy] [--timeFrame] [--startDate --endDate] Admin. totalCount for the same filters
|
|
13496
|
+
list-items [--name] [--includeQuickBooksDeactivationPending true] [--sortBy createdAt|updatedAt|name|cost|itemCategory|supplier] [--sortDir asc|desc] [--limit 1-100] [--cursor <token>] [--direction forward|backward]
|
|
13497
|
+
Returns { items, pageInfo }; follow nextCursor/previousCursor with the same filters and sort. --page/--perPage are rejected.
|
|
13498
|
+
count-items [same filter flags as list-items] total plus category and supplier facets
|
|
12229
13499
|
get-item <id>
|
|
12230
|
-
|
|
13500
|
+
get-item-quickbooks-sync-status <itemId> (saved status only; no provider call or polling)
|
|
13501
|
+
list-item-categories [--name] [--sortBy createdAt|name|itemCount|createdBy] [--sortDir asc|desc] [--limit 1-100] [--cursor <token>] [--direction forward|backward]
|
|
13502
|
+
Active categories only; returns { items, pageInfo }. Follow nextCursor/previousCursor with the same filters and sort. --page/--perPage are rejected.
|
|
13503
|
+
count-item-categories [--name] totalCount of active categories
|
|
12231
13504
|
create-item-category --name (admin)
|
|
12232
13505
|
update-item-category --id --name (authenticated; applies immediately)
|
|
12233
13506
|
delete-item-categories --ids <csv> (itemCategory.deleteItemCategories; admin; empty categories only)
|
|
12234
13507
|
|
|
12235
13508
|
Dashboard & users
|
|
12236
13509
|
whoami Show the user identity and role for the active API key.
|
|
12237
|
-
list-users
|
|
13510
|
+
list-users [--q] [--limit 1-100] [--cursor <token>]
|
|
13511
|
+
Name A\u2013Z. Returns { items, pageInfo }; follow nextCursor with the same --q. --page/--perPage are rejected.
|
|
13512
|
+
count-users [--q] totalCount for the same search
|
|
12238
13513
|
create-user --email <email> [--name <name>] [--role ${userRolesForHelp.join("|")}] (admin; API-only service identity with no Google sign-in)
|
|
12239
13514
|
create-api-key --name <label> [--userId <userId>] (defaults to the caller; admin required for another user; raw key is shown once)
|
|
12240
|
-
list-api-keys [--userId <userId>] (defaults to the caller; admin required for another user)
|
|
13515
|
+
list-api-keys [--userId <userId>] [--limit 1-100] [--cursor <token>] (newest first, { items, pageInfo }; defaults to the caller; admin required for another user)
|
|
12241
13516
|
revoke-api-key <apiKeyId> [--userId <userId>] (defaults to the caller; admin required for another user)
|
|
12242
13517
|
get-user-performance [--userId] (admin)
|
|
12243
13518
|
get-dashboard [--userId] [--role BD|CREATOR|INSIDE_SALES|ALL] [--deals ALL|SUCCESSFUL|LOST] [--timeFrame] [--startDate] [--endDate] (admin)
|
|
@@ -12247,12 +13522,31 @@ Dashboard & users
|
|
|
12247
13522
|
get-financial-overview [same optional flags as dashboard; role uses BudgetRole enum] (admin)
|
|
12248
13523
|
|
|
12249
13524
|
Errors
|
|
12250
|
-
get-recent-errors [--
|
|
13525
|
+
get-recent-errors [--cursor] [--direction forward|backward] [--limit] [--severity] [--status] [--timeFrame] (admin)
|
|
13526
|
+
count-errors [--severity] [--status] [--timeFrame] (admin)
|
|
13527
|
+
get-error <errorId> Full diagnostics: stack, cause, request, metadata (admin)
|
|
12251
13528
|
get-error-metrics (admin)
|
|
12252
13529
|
|
|
12253
13530
|
Automation (admin)
|
|
12254
|
-
list-integration-operations [--search] [--destination <provider,...>] [--status <PENDING|PROCESSING|FAILED|COMPLETED,...>] [--
|
|
12255
|
-
|
|
13531
|
+
list-integration-operations [--search] [--destination <provider,...>] [--status <PENDING|PROCESSING|FAILED|COMPLETED,...>] [--limit 1-100] [--cursor <token>] [--direction forward|backward]
|
|
13532
|
+
Newest first; returns { items, pageInfo }. Follow nextCursor/previousCursor with the same filters. --page/--perPage are rejected.
|
|
13533
|
+
count-integration-operations [same filter flags] provider filter options only (no total; filters do not change the result)
|
|
13534
|
+
get-integration-operation <operationId> (one job: who queued it, what it is for, saved progress, Retry state)
|
|
13535
|
+
retry-integration-operation <operationId> [--confirmExternalStateReconciled true|false] [--outboundEmailResolution ACCEPTED|NOT_ACCEPTED_RETRY] [--providerMessageId <id>] (QuickBooks jobs with a saved attempt check QuickBooks first: applied changes finish without resending, unapplied ones are sent again)
|
|
13536
|
+
reconcile-resource-operation <operationId> (admin: check a QuickBooks invoice/company/item job outcome without retrying; same check Retry runs first)
|
|
13537
|
+
|
|
13538
|
+
Webhooks (admin)
|
|
13539
|
+
list-webhook-event-types (event catalogue: type, group, live|planned)
|
|
13540
|
+
list-webhook-endpoints
|
|
13541
|
+
get-webhook-endpoint <endpointId>
|
|
13542
|
+
create-webhook-endpoint --name <name> --url <https-url> --events <type|prefix.*|*,...> [--enabled true|false] (prints the signing secret once)
|
|
13543
|
+
update-webhook-endpoint <endpointId> [--name] [--url] [--events <...>] [--enabled true|false]
|
|
13544
|
+
delete-webhook-endpoint <endpointId>
|
|
13545
|
+
rotate-webhook-secret <endpointId> [--previousSecretTtlHours <0-168>] (prints the new secret once)
|
|
13546
|
+
send-webhook-test-event <endpointId>
|
|
13547
|
+
list-webhook-deliveries [--endpointId] [--status PENDING|SUCCEEDED|FAILED] [--eventType] [--cursor] [--limit]
|
|
13548
|
+
get-webhook-delivery <deliveryId> (attempts with response codes)
|
|
13549
|
+
replay-webhook-delivery <deliveryId> (same eventId, new attempt chain)
|
|
12256
13550
|
|
|
12257
13551
|
Historical / benchmarks
|
|
12258
13552
|
get-approved-budgets [--projectId] [--limit] [--minRevenue] [--maxRevenue]
|
|
@@ -12594,6 +13888,8 @@ Waiting for approval\u2026
|
|
|
12594
13888
|
});
|
|
12595
13889
|
}
|
|
12596
13890
|
try {
|
|
13891
|
+
if (flags.q === true)
|
|
13892
|
+
throw new CliRuntimeError("USAGE", "--q needs a search value (--q <text> or --q=<text>). Use -q or --quiet to hide logs.");
|
|
12597
13893
|
if (runtime.env.BB_API_KEY?.trim()) {
|
|
12598
13894
|
configureAccessToken(undefined);
|
|
12599
13895
|
} else {
|
|
@@ -12625,21 +13921,49 @@ Waiting for approval\u2026
|
|
|
12625
13921
|
await whoAmI();
|
|
12626
13922
|
break;
|
|
12627
13923
|
}
|
|
12628
|
-
case "list-budgets":
|
|
13924
|
+
case "list-budgets":
|
|
13925
|
+
case "count-budgets": {
|
|
12629
13926
|
const statusStr = getFlag(flags, "status");
|
|
12630
13927
|
const statuses = parseCommaSeparatedBudgetStatuses(statusStr !== undefined ? String(statusStr) : undefined);
|
|
12631
|
-
|
|
13928
|
+
const filters = {
|
|
12632
13929
|
projectId: getFlag(flags, "projectId"),
|
|
12633
13930
|
name: getFlag(flags, "name"),
|
|
12634
13931
|
statuses,
|
|
12635
13932
|
createdBy: getFlag(flags, "createdBy"),
|
|
12636
13933
|
dateFrom: getFlag(flags, "dateFrom"),
|
|
12637
13934
|
dateTo: getFlag(flags, "dateTo"),
|
|
12638
|
-
active: parseBudgetActiveFlag(flags)
|
|
13935
|
+
active: parseBudgetActiveFlag(flags)
|
|
13936
|
+
};
|
|
13937
|
+
rejectRetiredPageFlags(flags);
|
|
13938
|
+
if (cmd === "count-budgets") {
|
|
13939
|
+
for (const key of [
|
|
13940
|
+
"limit",
|
|
13941
|
+
"cursor",
|
|
13942
|
+
"direction",
|
|
13943
|
+
"sortBy",
|
|
13944
|
+
"sortDir"
|
|
13945
|
+
]) {
|
|
13946
|
+
if (flags[key] !== undefined)
|
|
13947
|
+
throw new Error(`count-budgets does not accept --${key}; totals use filters only.`);
|
|
13948
|
+
}
|
|
13949
|
+
await countBudgets(filters);
|
|
13950
|
+
break;
|
|
13951
|
+
}
|
|
13952
|
+
for (const key of ["limit", "cursor", "direction", "sortBy", "sortDir"])
|
|
13953
|
+
rejectBareFlag(flags, key);
|
|
13954
|
+
const cursor = getFlag(flags, "cursor");
|
|
13955
|
+
if (cursor === "" || (cursor?.length ?? 0) > 8192)
|
|
13956
|
+
throw new Error("--cursor must be a non-empty opaque token of at most 8192 characters.");
|
|
13957
|
+
const direction = parseProjectDirection(getFlag(flags, "direction"));
|
|
13958
|
+
if (direction === "backward" && !cursor)
|
|
13959
|
+
throw new Error("--direction backward requires --cursor <token>.");
|
|
13960
|
+
await listBudgets({
|
|
13961
|
+
...filters,
|
|
13962
|
+
limit: parseProjectLimit(getFlag(flags, "limit")),
|
|
13963
|
+
cursor,
|
|
13964
|
+
direction,
|
|
12639
13965
|
sortBy: getFlag(flags, "sortBy"),
|
|
12640
13966
|
sortDir: getFlag(flags, "sortDir"),
|
|
12641
|
-
page: parsePositiveIntFlag(getFlag(flags, "page"), "--page"),
|
|
12642
|
-
perPage: parsePositiveIntFlag(getFlag(flags, "perPage"), "--perPage"),
|
|
12643
13967
|
includeDetails: flags.summary === true ? false : parseOptionalBoolFlag(flags, "includeDetails") ?? true
|
|
12644
13968
|
});
|
|
12645
13969
|
break;
|
|
@@ -12692,7 +14016,19 @@ Waiting for approval\u2026
|
|
|
12692
14016
|
break;
|
|
12693
14017
|
}
|
|
12694
14018
|
case "get-budget-categories": {
|
|
12695
|
-
|
|
14019
|
+
rejectRetiredPageFlags(flags);
|
|
14020
|
+
for (const key of ["limit", "cursor"])
|
|
14021
|
+
rejectBareFlag(flags, key);
|
|
14022
|
+
if (flags.direction !== undefined)
|
|
14023
|
+
throw new Error("get-budget-categories pages forward only; follow pageInfo.nextCursor with --cursor.");
|
|
14024
|
+
const cursor = getFlag(flags, "cursor");
|
|
14025
|
+
if (cursor === "" || (cursor?.length ?? 0) > 8192)
|
|
14026
|
+
throw new Error("--cursor must be a non-empty opaque token of at most 8192 characters.");
|
|
14027
|
+
await getBudgetCategories({
|
|
14028
|
+
q: getFlag(flags, "q"),
|
|
14029
|
+
limit: parseProjectLimit(getFlag(flags, "limit")),
|
|
14030
|
+
cursor
|
|
14031
|
+
});
|
|
12696
14032
|
break;
|
|
12697
14033
|
}
|
|
12698
14034
|
case "get-budget-versions": {
|
|
@@ -12704,7 +14040,7 @@ Waiting for approval\u2026
|
|
|
12704
14040
|
throw new CliRuntimeError("USAGE", "--limit must be an integer from 1 to 50.");
|
|
12705
14041
|
}
|
|
12706
14042
|
if (flags.cursor === true || flags.cursor === "") {
|
|
12707
|
-
throw new CliRuntimeError("USAGE", "--cursor requires
|
|
14043
|
+
throw new CliRuntimeError("USAGE", "--cursor requires the nextCursor token from the previous page.");
|
|
12708
14044
|
}
|
|
12709
14045
|
await getBudgetVersions(id, {
|
|
12710
14046
|
limit,
|
|
@@ -12985,6 +14321,14 @@ Waiting for approval\u2026
|
|
|
12985
14321
|
});
|
|
12986
14322
|
break;
|
|
12987
14323
|
}
|
|
14324
|
+
case "count-bills": {
|
|
14325
|
+
await countBills(parseCountBillsFlags(flags));
|
|
14326
|
+
break;
|
|
14327
|
+
}
|
|
14328
|
+
case "count-claims": {
|
|
14329
|
+
await countBills({ ...parseCountBillsFlags(flags), isClaimable: true });
|
|
14330
|
+
break;
|
|
14331
|
+
}
|
|
12988
14332
|
case "create-bill-approval": {
|
|
12989
14333
|
const id = positional[0];
|
|
12990
14334
|
if (!id)
|
|
@@ -13182,10 +14526,25 @@ Waiting for approval\u2026
|
|
|
13182
14526
|
break;
|
|
13183
14527
|
}
|
|
13184
14528
|
case "get-bill-attachments": {
|
|
14529
|
+
const page = parseDetailFeedPage("get-bill-attachments", "<billId>", positional, flags, 50);
|
|
14530
|
+
await getBillAttachments(page);
|
|
14531
|
+
break;
|
|
14532
|
+
}
|
|
14533
|
+
case "get-bill-approvals": {
|
|
14534
|
+
const page = parseDetailFeedPage("get-bill-approvals", "<billId>", positional, flags, 50);
|
|
14535
|
+
await getBillApprovals(page);
|
|
14536
|
+
break;
|
|
14537
|
+
}
|
|
14538
|
+
case "get-bill-line-items": {
|
|
14539
|
+
const page = parseDetailFeedPage("get-bill-line-items", "<billId>", positional, flags, 100);
|
|
14540
|
+
await getBillLineItems(page);
|
|
14541
|
+
break;
|
|
14542
|
+
}
|
|
14543
|
+
case "get-bill-payment": {
|
|
13185
14544
|
const id = positional[0];
|
|
13186
14545
|
if (!id)
|
|
13187
|
-
throw new Error("get-bill-
|
|
13188
|
-
await
|
|
14546
|
+
throw new Error("get-bill-payment requires <billId>");
|
|
14547
|
+
await getBillPayment(id);
|
|
13189
14548
|
break;
|
|
13190
14549
|
}
|
|
13191
14550
|
case "stage-bill-attachment": {
|
|
@@ -13278,18 +14637,32 @@ Waiting for approval\u2026
|
|
|
13278
14637
|
break;
|
|
13279
14638
|
}
|
|
13280
14639
|
case "list-quotations": {
|
|
13281
|
-
|
|
13282
|
-
const
|
|
13283
|
-
|
|
14640
|
+
rejectRetiredPageFlags(flags);
|
|
14641
|
+
for (const key of ["limit", "cursor", "direction"])
|
|
14642
|
+
rejectBareFlag(flags, key);
|
|
14643
|
+
const cursor = getFlag(flags, "cursor");
|
|
14644
|
+
if (cursor === "" || (cursor?.length ?? 0) > 8192)
|
|
14645
|
+
throw new Error("--cursor must be a non-empty opaque token of at most 8192 characters.");
|
|
14646
|
+
const direction = parseProjectDirection(getFlag(flags, "direction"));
|
|
14647
|
+
if (direction === "backward" && !cursor)
|
|
14648
|
+
throw new Error("--direction backward requires --cursor <token>.");
|
|
13284
14649
|
await listQuotations({
|
|
13285
|
-
|
|
13286
|
-
|
|
13287
|
-
|
|
13288
|
-
|
|
13289
|
-
|
|
13290
|
-
|
|
13291
|
-
|
|
13292
|
-
|
|
14650
|
+
...parseQuotationFilterFlags(flags),
|
|
14651
|
+
limit: parseProjectLimit(getFlag(flags, "limit")),
|
|
14652
|
+
cursor,
|
|
14653
|
+
direction
|
|
14654
|
+
});
|
|
14655
|
+
break;
|
|
14656
|
+
}
|
|
14657
|
+
case "count-quotations": {
|
|
14658
|
+
rejectRetiredPageFlags(flags);
|
|
14659
|
+
for (const key of ["limit", "cursor", "direction"]) {
|
|
14660
|
+
if (flags[key] !== undefined)
|
|
14661
|
+
throw new Error(`count-quotations does not accept --${key}; totals use filters only.`);
|
|
14662
|
+
}
|
|
14663
|
+
await countQuotations({
|
|
14664
|
+
...parseQuotationFilterFlags(flags),
|
|
14665
|
+
includeMetrics: parseOptionalBoolFlag(flags, "includeMetrics") ?? false
|
|
13293
14666
|
});
|
|
13294
14667
|
break;
|
|
13295
14668
|
}
|
|
@@ -13300,6 +14673,11 @@ Waiting for approval\u2026
|
|
|
13300
14673
|
await getQuotationDetails(id);
|
|
13301
14674
|
break;
|
|
13302
14675
|
}
|
|
14676
|
+
case "get-quotation-line-items": {
|
|
14677
|
+
const page = parseDetailFeedPage("get-quotation-line-items", "<quotationId>", positional, flags, 100);
|
|
14678
|
+
await getQuotationLineItems(page);
|
|
14679
|
+
break;
|
|
14680
|
+
}
|
|
13303
14681
|
case "upload-quotation-attachment": {
|
|
13304
14682
|
const [projectId, filePath] = positional;
|
|
13305
14683
|
if (!projectId || !filePath) {
|
|
@@ -13411,7 +14789,8 @@ Waiting for approval\u2026
|
|
|
13411
14789
|
await listAvailableQboCustomerInvoices(budgetId);
|
|
13412
14790
|
break;
|
|
13413
14791
|
}
|
|
13414
|
-
case "list-customer-invoices":
|
|
14792
|
+
case "list-customer-invoices":
|
|
14793
|
+
case "count-customer-invoices": {
|
|
13415
14794
|
const positionalBudgetId = positional[0];
|
|
13416
14795
|
const projectId = getFlag(flags, "projectId");
|
|
13417
14796
|
const projectIds = parseCommaSeparatedIds(getFlag(flags, "projectIds"));
|
|
@@ -13423,17 +14802,44 @@ Waiting for approval\u2026
|
|
|
13423
14802
|
...parseCommaSeparatedIds(getFlag(flags, "budgetIds")) ?? []
|
|
13424
14803
|
];
|
|
13425
14804
|
const statusRaw = getFlag(flags, "status");
|
|
13426
|
-
const
|
|
13427
|
-
await listCustomerInvoices({
|
|
14805
|
+
const filters = {
|
|
13428
14806
|
scope: projectId ? { type: "project", projectId } : { type: "global" },
|
|
13429
|
-
page: parsePositiveIntFlag(getFlag(flags, "page"), "--page") ?? 1,
|
|
13430
|
-
perPage: parsePositiveIntFlag(getFlag(flags, "perPage"), "--perPage") ?? 20,
|
|
13431
14807
|
q: getFlag(flags, "search") ?? "",
|
|
13432
14808
|
statuses: parseCommaSeparatedCustomerInvoiceStatuses(statusRaw !== undefined ? String(statusRaw) : undefined),
|
|
13433
14809
|
companyIds: parseCommaSeparatedIds(getFlag(flags, "companyIds")),
|
|
13434
14810
|
projectIds,
|
|
13435
14811
|
budgetIds: budgetIds.length > 0 ? [...new Set(budgetIds)] : undefined,
|
|
13436
|
-
createdByIds: parseCommaSeparatedIds(getFlag(flags, "createdByIds"))
|
|
14812
|
+
createdByIds: parseCommaSeparatedIds(getFlag(flags, "createdByIds"))
|
|
14813
|
+
};
|
|
14814
|
+
rejectRetiredPageFlags(flags);
|
|
14815
|
+
if (cmd === "count-customer-invoices") {
|
|
14816
|
+
for (const key of [
|
|
14817
|
+
"limit",
|
|
14818
|
+
"cursor",
|
|
14819
|
+
"direction",
|
|
14820
|
+
"sortBy",
|
|
14821
|
+
"sortDir"
|
|
14822
|
+
]) {
|
|
14823
|
+
if (flags[key] !== undefined)
|
|
14824
|
+
throw new Error(`count-customer-invoices does not accept --${key}; totals use filters only.`);
|
|
14825
|
+
}
|
|
14826
|
+
await countCustomerInvoices(filters);
|
|
14827
|
+
break;
|
|
14828
|
+
}
|
|
14829
|
+
for (const key of ["limit", "cursor", "direction", "sortBy", "sortDir"])
|
|
14830
|
+
rejectBareFlag(flags, key);
|
|
14831
|
+
const cursor = getFlag(flags, "cursor");
|
|
14832
|
+
if (cursor === "" || (cursor?.length ?? 0) > 8192)
|
|
14833
|
+
throw new Error("--cursor must be a non-empty opaque token of at most 8192 characters.");
|
|
14834
|
+
const direction = parseProjectDirection(getFlag(flags, "direction"));
|
|
14835
|
+
if (direction === "backward" && !cursor)
|
|
14836
|
+
throw new Error("--direction backward requires --cursor <token>.");
|
|
14837
|
+
const sortDir = parseOptionalBillListSortDir(getFlag(flags, "sortDir"));
|
|
14838
|
+
await listCustomerInvoices({
|
|
14839
|
+
...filters,
|
|
14840
|
+
limit: parseProjectLimit(getFlag(flags, "limit")),
|
|
14841
|
+
cursor,
|
|
14842
|
+
direction,
|
|
13437
14843
|
sortBy: parseCustomerInvoiceSortBy(getFlag(flags, "sortBy")),
|
|
13438
14844
|
sortDir: sortDir ?? "desc"
|
|
13439
14845
|
});
|
|
@@ -13447,6 +14853,28 @@ Waiting for approval\u2026
|
|
|
13447
14853
|
await getCustomerInvoice(batchId);
|
|
13448
14854
|
break;
|
|
13449
14855
|
}
|
|
14856
|
+
case "get-customer-invoice-invoices": {
|
|
14857
|
+
const batchId = positional[0];
|
|
14858
|
+
if (!batchId)
|
|
14859
|
+
throw new Error("get-customer-invoice-invoices requires <batchId>");
|
|
14860
|
+
await getCustomerInvoiceInvoices(batchId);
|
|
14861
|
+
break;
|
|
14862
|
+
}
|
|
14863
|
+
case "get-customer-invoice-lines": {
|
|
14864
|
+
const page = parseDetailFeedPage("get-customer-invoice-lines", "<invoiceId>", positional, flags, 100);
|
|
14865
|
+
await getCustomerInvoiceLines(page);
|
|
14866
|
+
break;
|
|
14867
|
+
}
|
|
14868
|
+
case "get-customer-invoice-approvals": {
|
|
14869
|
+
const page = parseDetailFeedPage("get-customer-invoice-approvals", "<batchId>", positional, flags, 50);
|
|
14870
|
+
await getCustomerInvoiceApprovals(page);
|
|
14871
|
+
break;
|
|
14872
|
+
}
|
|
14873
|
+
case "get-customer-invoice-history": {
|
|
14874
|
+
const page = parseDetailFeedPage("get-customer-invoice-history", "<batchId>", positional, flags, 100);
|
|
14875
|
+
await getCustomerInvoiceHistory(page);
|
|
14876
|
+
break;
|
|
14877
|
+
}
|
|
13450
14878
|
case "get-customer-invoice-email-context": {
|
|
13451
14879
|
const batchId = positional[0];
|
|
13452
14880
|
if (!batchId) {
|
|
@@ -13612,13 +15040,11 @@ Waiting for approval\u2026
|
|
|
13612
15040
|
break;
|
|
13613
15041
|
}
|
|
13614
15042
|
case "list-companies": {
|
|
13615
|
-
await listCompanies(
|
|
13616
|
-
|
|
13617
|
-
|
|
13618
|
-
|
|
13619
|
-
|
|
13620
|
-
perPage: parsePositiveIntFlag(getFlag(flags, "perPage"), "--perPage")
|
|
13621
|
-
});
|
|
15043
|
+
await listCompanies(parseCompanyListFlags(flags));
|
|
15044
|
+
break;
|
|
15045
|
+
}
|
|
15046
|
+
case "count-companies": {
|
|
15047
|
+
await countCompanies(parseCompanyCountFlags(flags));
|
|
13622
15048
|
break;
|
|
13623
15049
|
}
|
|
13624
15050
|
case "get-company": {
|
|
@@ -13645,7 +15071,17 @@ Waiting for approval\u2026
|
|
|
13645
15071
|
const query = getFlag(flags, "query");
|
|
13646
15072
|
if (!query)
|
|
13647
15073
|
throw new Error("search-existing-companies requires --query <name>");
|
|
13648
|
-
|
|
15074
|
+
rejectRetiredPageFlags(flags);
|
|
15075
|
+
for (const key of ["limit", "cursor"])
|
|
15076
|
+
rejectBareFlag(flags, key);
|
|
15077
|
+
const cursor = getFlag(flags, "cursor");
|
|
15078
|
+
if (cursor === "" || (cursor?.length ?? 0) > 8192)
|
|
15079
|
+
throw new Error("--cursor must be a non-empty opaque token of at most 8192 characters.");
|
|
15080
|
+
const limitFlag = getFlag(flags, "limit");
|
|
15081
|
+
const limit = limitFlag === undefined ? undefined : Number(limitFlag);
|
|
15082
|
+
if (limit !== undefined && (!Number.isInteger(limit) || limit < 1 || limit > 50))
|
|
15083
|
+
throw new Error("--limit must be an integer from 1 to 50.");
|
|
15084
|
+
await searchExistingCompanies({ query, limit, cursor });
|
|
13649
15085
|
break;
|
|
13650
15086
|
}
|
|
13651
15087
|
case "use-existing-company": {
|
|
@@ -13678,6 +15114,13 @@ Waiting for approval\u2026
|
|
|
13678
15114
|
await updateCompanyFromPayload(raw);
|
|
13679
15115
|
break;
|
|
13680
15116
|
}
|
|
15117
|
+
case "get-company-quickbooks-sync-status": {
|
|
15118
|
+
const id = positional[0];
|
|
15119
|
+
if (!id)
|
|
15120
|
+
throw new Error("get-company-quickbooks-sync-status requires <companyId>");
|
|
15121
|
+
await getCompanyQuickBooksSyncStatus(id);
|
|
15122
|
+
break;
|
|
15123
|
+
}
|
|
13681
15124
|
case "delete-company": {
|
|
13682
15125
|
const id = positional[0];
|
|
13683
15126
|
if (!id)
|
|
@@ -13686,23 +15129,46 @@ Waiting for approval\u2026
|
|
|
13686
15129
|
break;
|
|
13687
15130
|
}
|
|
13688
15131
|
case "list-projects": {
|
|
13689
|
-
|
|
13690
|
-
await listProjects({
|
|
13691
|
-
companyId: getFlag(flags, "companyId"),
|
|
13692
|
-
name: getFlag(flags, "name"),
|
|
13693
|
-
status: parseOptionalExtendedProjectStatus(statusRaw !== undefined ? String(statusRaw) : undefined),
|
|
13694
|
-
active: parseOptionalBoolFlag(flags, "active"),
|
|
13695
|
-
page: parsePositiveIntFlag(getFlag(flags, "page"), "--page"),
|
|
13696
|
-
perPage: parsePositiveIntFlag(getFlag(flags, "perPage"), "--perPage")
|
|
13697
|
-
});
|
|
15132
|
+
await listProjects(parseProjectListFlags(flags));
|
|
13698
15133
|
break;
|
|
13699
15134
|
}
|
|
13700
|
-
case "
|
|
13701
|
-
await
|
|
15135
|
+
case "count-projects": {
|
|
15136
|
+
await countProjects(parseProjectCountFlags(flags));
|
|
15137
|
+
break;
|
|
15138
|
+
}
|
|
15139
|
+
case "list-project-hubs":
|
|
15140
|
+
case "count-project-hubs": {
|
|
15141
|
+
rejectRetiredPageFlags(flags);
|
|
15142
|
+
const filters = {
|
|
13702
15143
|
q: getFlag(flags, "q"),
|
|
13703
|
-
statuses: parseCommaSeparatedProjectStatuses(getFlag(flags, "status"))
|
|
13704
|
-
|
|
13705
|
-
|
|
15144
|
+
statuses: parseCommaSeparatedProjectStatuses(getFlag(flags, "status"))
|
|
15145
|
+
};
|
|
15146
|
+
if (cmd === "count-project-hubs") {
|
|
15147
|
+
for (const key of [
|
|
15148
|
+
"limit",
|
|
15149
|
+
"cursor",
|
|
15150
|
+
"direction",
|
|
15151
|
+
"sortBy",
|
|
15152
|
+
"sortDir"
|
|
15153
|
+
])
|
|
15154
|
+
if (flags[key] !== undefined)
|
|
15155
|
+
throw new Error(`count-project-hubs does not accept --${key}; totals use filters only.`);
|
|
15156
|
+
await countProjectHubs(filters);
|
|
15157
|
+
break;
|
|
15158
|
+
}
|
|
15159
|
+
for (const key of ["limit", "cursor", "direction", "sortBy", "sortDir"])
|
|
15160
|
+
rejectBareFlag(flags, key);
|
|
15161
|
+
const cursor = getFlag(flags, "cursor");
|
|
15162
|
+
if (cursor === "" || (cursor?.length ?? 0) > 8192)
|
|
15163
|
+
throw new Error("--cursor must be a non-empty opaque token of at most 8192 characters.");
|
|
15164
|
+
const direction = parseProjectDirection(getFlag(flags, "direction"));
|
|
15165
|
+
if (direction === "backward" && !cursor)
|
|
15166
|
+
throw new Error("--direction backward requires --cursor <token>.");
|
|
15167
|
+
await listProjectHubs({
|
|
15168
|
+
...filters,
|
|
15169
|
+
limit: parseProjectLimit(getFlag(flags, "limit")),
|
|
15170
|
+
cursor,
|
|
15171
|
+
direction,
|
|
13706
15172
|
sortBy: parseOptionalProjectHubSortBy(getFlag(flags, "sortBy")),
|
|
13707
15173
|
sortDir: parseOptionalBillListSortDir(getFlag(flags, "sortDir"))
|
|
13708
15174
|
});
|
|
@@ -13871,6 +15337,10 @@ Waiting for approval\u2026
|
|
|
13871
15337
|
await updateContactPersonFromPayload(raw);
|
|
13872
15338
|
break;
|
|
13873
15339
|
}
|
|
15340
|
+
case "count-suppliers": {
|
|
15341
|
+
await countSuppliers(parseCountSuppliersFlags(flags));
|
|
15342
|
+
break;
|
|
15343
|
+
}
|
|
13874
15344
|
case "list-suppliers": {
|
|
13875
15345
|
await listSuppliers(parseListSuppliersFlags(flags));
|
|
13876
15346
|
break;
|
|
@@ -13945,22 +15415,117 @@ Waiting for approval\u2026
|
|
|
13945
15415
|
await createSupplierTagOption(String(name));
|
|
13946
15416
|
break;
|
|
13947
15417
|
}
|
|
13948
|
-
case "get-supplier-analytics":
|
|
15418
|
+
case "get-supplier-analytics":
|
|
15419
|
+
case "count-supplier-analytics": {
|
|
15420
|
+
rejectRetiredPageFlags(flags);
|
|
13949
15421
|
const tfRaw = getFlag(flags, "timeFrame");
|
|
13950
|
-
|
|
15422
|
+
for (const key of [
|
|
15423
|
+
"name",
|
|
15424
|
+
"status",
|
|
15425
|
+
"gstRegistered",
|
|
15426
|
+
"createdBy",
|
|
15427
|
+
"startDate",
|
|
15428
|
+
"endDate",
|
|
15429
|
+
"timeFrame"
|
|
15430
|
+
])
|
|
15431
|
+
rejectBareFlag(flags, key);
|
|
15432
|
+
const timeFrame = parseOptionalSupplierAnalyticsTimeFrame(tfRaw !== undefined ? String(tfRaw) : undefined);
|
|
15433
|
+
const startDate = getFlag(flags, "startDate");
|
|
15434
|
+
const endDate = getFlag(flags, "endDate");
|
|
15435
|
+
if ((startDate || endDate) && timeFrame !== "CUSTOM")
|
|
15436
|
+
throw new Error("--startDate/--endDate need --timeFrame CUSTOM; other time frames ignore them.");
|
|
15437
|
+
const statusRaw = getFlag(flags, "status");
|
|
15438
|
+
const status = statusRaw?.split(",").map((value) => value.trim()).filter(Boolean);
|
|
15439
|
+
const badStatus = status?.find((value) => !Object.values(ApprovalStatus2).some((s) => s === value));
|
|
15440
|
+
if (badStatus)
|
|
15441
|
+
throw new Error(`Invalid --status ${badStatus}. Use a comma list of: ${Object.values(ApprovalStatus2).join(", ")}.`);
|
|
15442
|
+
const gstRaw = getFlag(flags, "gstRegistered");
|
|
15443
|
+
if (gstRaw !== undefined && gstRaw !== "true" && gstRaw !== "false")
|
|
15444
|
+
throw new Error("--gstRegistered must be true or false.");
|
|
15445
|
+
const filters = {
|
|
13951
15446
|
name: getFlag(flags, "name"),
|
|
13952
|
-
|
|
13953
|
-
|
|
13954
|
-
|
|
15447
|
+
timeFrame,
|
|
15448
|
+
status: status?.length ? status : undefined,
|
|
15449
|
+
gstRegistered: gstRaw === undefined ? undefined : gstRaw === "true",
|
|
15450
|
+
createdBy: getFlag(flags, "createdBy"),
|
|
15451
|
+
startDate,
|
|
15452
|
+
endDate
|
|
15453
|
+
};
|
|
15454
|
+
if (cmd === "count-supplier-analytics") {
|
|
15455
|
+
for (const key of [
|
|
15456
|
+
"limit",
|
|
15457
|
+
"cursor",
|
|
15458
|
+
"direction",
|
|
15459
|
+
"sortBy",
|
|
15460
|
+
"sortDir"
|
|
15461
|
+
])
|
|
15462
|
+
if (flags[key] !== undefined)
|
|
15463
|
+
throw new Error(`count-supplier-analytics does not accept --${key}; totals use filters only.`);
|
|
15464
|
+
await countSupplierAnalytics(filters);
|
|
15465
|
+
break;
|
|
15466
|
+
}
|
|
15467
|
+
for (const key of ["limit", "cursor", "direction", "sortBy", "sortDir"])
|
|
15468
|
+
rejectBareFlag(flags, key);
|
|
15469
|
+
const cursor = getFlag(flags, "cursor");
|
|
15470
|
+
if (cursor === "" || (cursor?.length ?? 0) > 8192)
|
|
15471
|
+
throw new Error("--cursor must be a non-empty opaque token of at most 8192 characters.");
|
|
15472
|
+
const direction = parseProjectDirection(getFlag(flags, "direction"));
|
|
15473
|
+
if (direction === "backward" && !cursor)
|
|
15474
|
+
throw new Error("--direction backward requires --cursor <token>.");
|
|
15475
|
+
const sortBy = getFlag(flags, "sortBy");
|
|
15476
|
+
if (sortBy !== undefined && !SUPPLIER_ANALYTICS_SORT_IDS.some((id) => id === sortBy))
|
|
15477
|
+
throw new Error(`--sortBy must be one of: ${SUPPLIER_ANALYTICS_SORT_IDS.join(", ")}.`);
|
|
15478
|
+
await getSupplierAnalytics({
|
|
15479
|
+
...filters,
|
|
15480
|
+
limit: parseProjectLimit(getFlag(flags, "limit")),
|
|
15481
|
+
cursor,
|
|
15482
|
+
direction,
|
|
15483
|
+
sortBy: SUPPLIER_ANALYTICS_SORT_IDS.find((id) => id === sortBy),
|
|
15484
|
+
sortDir: parseOptionalBillListSortDir(getFlag(flags, "sortDir"))
|
|
13955
15485
|
});
|
|
13956
15486
|
break;
|
|
13957
15487
|
}
|
|
13958
|
-
case "list-items":
|
|
13959
|
-
|
|
15488
|
+
case "list-items":
|
|
15489
|
+
case "count-items": {
|
|
15490
|
+
rejectRetiredPageFlags(flags);
|
|
15491
|
+
const filters = {
|
|
13960
15492
|
includeQuickBooksDeactivationPending: flags.includeQuickBooksDeactivationPending === true ? true : parseOptionalBoolFlag(flags, "includeQuickBooksDeactivationPending"),
|
|
13961
|
-
name: getFlag(flags, "name")
|
|
13962
|
-
|
|
13963
|
-
|
|
15493
|
+
name: getFlag(flags, "name")
|
|
15494
|
+
};
|
|
15495
|
+
if (cmd === "count-items") {
|
|
15496
|
+
for (const key of [
|
|
15497
|
+
"limit",
|
|
15498
|
+
"cursor",
|
|
15499
|
+
"direction",
|
|
15500
|
+
"sortBy",
|
|
15501
|
+
"sortDir"
|
|
15502
|
+
])
|
|
15503
|
+
if (flags[key] !== undefined)
|
|
15504
|
+
throw new Error(`count-items does not accept --${key}; totals use filters only.`);
|
|
15505
|
+
await countItems(filters);
|
|
15506
|
+
break;
|
|
15507
|
+
}
|
|
15508
|
+
for (const key of ["limit", "cursor", "direction", "sortBy", "sortDir"])
|
|
15509
|
+
rejectBareFlag(flags, key);
|
|
15510
|
+
const cursor = getFlag(flags, "cursor");
|
|
15511
|
+
if (cursor === "" || (cursor?.length ?? 0) > 8192)
|
|
15512
|
+
throw new Error("--cursor must be a non-empty opaque token of at most 8192 characters.");
|
|
15513
|
+
const direction = parseProjectDirection(getFlag(flags, "direction"));
|
|
15514
|
+
if (direction === "backward" && !cursor)
|
|
15515
|
+
throw new Error("--direction backward requires --cursor <token>.");
|
|
15516
|
+
const sortBy = getFlag(flags, "sortBy");
|
|
15517
|
+
const sortId = INVENTORY_SORT_IDS.find((id) => id === sortBy);
|
|
15518
|
+
if (sortBy !== undefined && !sortId)
|
|
15519
|
+
throw new Error(`Invalid --sortBy "${sortBy}". Use one of: ${INVENTORY_SORT_IDS.join(", ")}.`);
|
|
15520
|
+
const sortDir = getFlag(flags, "sortDir");
|
|
15521
|
+
if (sortDir !== undefined && sortDir !== "asc" && sortDir !== "desc")
|
|
15522
|
+
throw new Error('--sortDir must be "asc" or "desc".');
|
|
15523
|
+
await listItems({
|
|
15524
|
+
...filters,
|
|
15525
|
+
limit: parseProjectLimit(getFlag(flags, "limit")),
|
|
15526
|
+
cursor,
|
|
15527
|
+
direction,
|
|
15528
|
+
sort: sortId ? [{ id: sortId, desc: sortDir !== "asc" }] : undefined
|
|
13964
15529
|
});
|
|
13965
15530
|
break;
|
|
13966
15531
|
}
|
|
@@ -13971,6 +15536,14 @@ Waiting for approval\u2026
|
|
|
13971
15536
|
await getItem(id);
|
|
13972
15537
|
break;
|
|
13973
15538
|
}
|
|
15539
|
+
case "get-item-quickbooks-sync-status": {
|
|
15540
|
+
const id = positional[0];
|
|
15541
|
+
if (!id) {
|
|
15542
|
+
throw new Error("get-item-quickbooks-sync-status requires <itemId>");
|
|
15543
|
+
}
|
|
15544
|
+
await getItemQuickBooksSyncStatus(id);
|
|
15545
|
+
break;
|
|
15546
|
+
}
|
|
13974
15547
|
case "create-item": {
|
|
13975
15548
|
const payloadRaw = getFlag(flags, "payload");
|
|
13976
15549
|
if (!payloadRaw) {
|
|
@@ -14008,10 +15581,45 @@ Waiting for approval\u2026
|
|
|
14008
15581
|
await archiveItemsByIds(ids);
|
|
14009
15582
|
break;
|
|
14010
15583
|
}
|
|
14011
|
-
case "list-item-categories":
|
|
15584
|
+
case "list-item-categories":
|
|
15585
|
+
case "count-item-categories": {
|
|
15586
|
+
rejectRetiredPageFlags(flags);
|
|
15587
|
+
const filters = { name: getFlag(flags, "name") };
|
|
15588
|
+
if (cmd === "count-item-categories") {
|
|
15589
|
+
for (const key of [
|
|
15590
|
+
"limit",
|
|
15591
|
+
"cursor",
|
|
15592
|
+
"direction",
|
|
15593
|
+
"sortBy",
|
|
15594
|
+
"sortDir"
|
|
15595
|
+
])
|
|
15596
|
+
if (flags[key] !== undefined)
|
|
15597
|
+
throw new Error(`count-item-categories does not accept --${key}; totals use filters only.`);
|
|
15598
|
+
await countItemCategories(filters);
|
|
15599
|
+
break;
|
|
15600
|
+
}
|
|
15601
|
+
for (const key of ["limit", "cursor", "direction", "sortBy", "sortDir"])
|
|
15602
|
+
rejectBareFlag(flags, key);
|
|
15603
|
+
const cursor = getFlag(flags, "cursor");
|
|
15604
|
+
if (cursor === "" || (cursor?.length ?? 0) > 8192)
|
|
15605
|
+
throw new Error("--cursor must be a non-empty opaque token of at most 8192 characters.");
|
|
15606
|
+
const direction = parseProjectDirection(getFlag(flags, "direction"));
|
|
15607
|
+
if (direction === "backward" && !cursor)
|
|
15608
|
+
throw new Error("--direction backward requires --cursor <token>.");
|
|
15609
|
+
const sortByRaw = getFlag(flags, "sortBy");
|
|
15610
|
+
const sortBy = ITEM_CATEGORY_SORT_IDS.find((id) => id === sortByRaw);
|
|
15611
|
+
if (sortByRaw !== undefined && !sortBy)
|
|
15612
|
+
throw new Error(`Invalid --sortBy "${sortByRaw}". Use one of: ${ITEM_CATEGORY_SORT_IDS.join(", ")}.`);
|
|
15613
|
+
const sortDir = getFlag(flags, "sortDir");
|
|
15614
|
+
if (sortDir !== undefined && sortDir !== "asc" && sortDir !== "desc")
|
|
15615
|
+
throw new Error('--sortDir must be "asc" or "desc".');
|
|
14012
15616
|
await listItemCategories({
|
|
14013
|
-
|
|
14014
|
-
|
|
15617
|
+
...filters,
|
|
15618
|
+
limit: parseProjectLimit(getFlag(flags, "limit")),
|
|
15619
|
+
cursor,
|
|
15620
|
+
direction,
|
|
15621
|
+
sortBy,
|
|
15622
|
+
sortDir
|
|
14015
15623
|
});
|
|
14016
15624
|
break;
|
|
14017
15625
|
}
|
|
@@ -14043,8 +15651,29 @@ Waiting for approval\u2026
|
|
|
14043
15651
|
await deleteItemCategoriesByIds(ids);
|
|
14044
15652
|
break;
|
|
14045
15653
|
}
|
|
14046
|
-
case "list-users":
|
|
14047
|
-
|
|
15654
|
+
case "list-users":
|
|
15655
|
+
case "count-users": {
|
|
15656
|
+
rejectRetiredPageFlags(flags);
|
|
15657
|
+
const q = getFlag(flags, "q");
|
|
15658
|
+
if (cmd === "count-users") {
|
|
15659
|
+
for (const key of ["limit", "cursor"])
|
|
15660
|
+
if (flags[key] !== undefined)
|
|
15661
|
+
throw new Error(`count-users does not accept --${key}; totals use --q only.`);
|
|
15662
|
+
await countUsers({ q });
|
|
15663
|
+
break;
|
|
15664
|
+
}
|
|
15665
|
+
for (const key of ["limit", "cursor"])
|
|
15666
|
+
rejectBareFlag(flags, key);
|
|
15667
|
+
if (flags.direction !== undefined)
|
|
15668
|
+
throw new Error("list-users pages forward only; follow pageInfo.nextCursor with --cursor.");
|
|
15669
|
+
const cursor = getFlag(flags, "cursor");
|
|
15670
|
+
if (cursor === "" || (cursor?.length ?? 0) > 8192)
|
|
15671
|
+
throw new Error("--cursor must be a non-empty opaque token of at most 8192 characters.");
|
|
15672
|
+
await listUsers({
|
|
15673
|
+
q,
|
|
15674
|
+
limit: parseProjectLimit(getFlag(flags, "limit")),
|
|
15675
|
+
cursor
|
|
15676
|
+
});
|
|
14048
15677
|
break;
|
|
14049
15678
|
}
|
|
14050
15679
|
case "create-user": {
|
|
@@ -14069,7 +15698,23 @@ Waiting for approval\u2026
|
|
|
14069
15698
|
break;
|
|
14070
15699
|
}
|
|
14071
15700
|
case "list-api-keys": {
|
|
14072
|
-
|
|
15701
|
+
rejectRetiredPageFlags(flags);
|
|
15702
|
+
for (const key of ["limit", "cursor"])
|
|
15703
|
+
rejectBareFlag(flags, key);
|
|
15704
|
+
if (flags.direction !== undefined)
|
|
15705
|
+
throw new Error("list-api-keys pages forward only; follow pageInfo.nextCursor with --cursor.");
|
|
15706
|
+
const cursor = getFlag(flags, "cursor");
|
|
15707
|
+
if (cursor === "" || (cursor?.length ?? 0) > 8192)
|
|
15708
|
+
throw new Error("--cursor must be a non-empty opaque token of at most 8192 characters.");
|
|
15709
|
+
const limitFlag = getFlag(flags, "limit");
|
|
15710
|
+
const limit = limitFlag === undefined ? undefined : Number(limitFlag);
|
|
15711
|
+
if (limit !== undefined && (!Number.isInteger(limit) || limit < 1 || limit > 100))
|
|
15712
|
+
throw new Error("--limit must be an integer from 1 to 100.");
|
|
15713
|
+
await listApiKeysForUser({
|
|
15714
|
+
userId: getFlag(flags, "userId"),
|
|
15715
|
+
limit,
|
|
15716
|
+
cursor
|
|
15717
|
+
});
|
|
14073
15718
|
break;
|
|
14074
15719
|
}
|
|
14075
15720
|
case "revoke-api-key": {
|
|
@@ -14114,29 +15759,88 @@ Waiting for approval\u2026
|
|
|
14114
15759
|
});
|
|
14115
15760
|
break;
|
|
14116
15761
|
}
|
|
14117
|
-
case "get-recent-errors":
|
|
14118
|
-
|
|
14119
|
-
|
|
14120
|
-
|
|
15762
|
+
case "get-recent-errors":
|
|
15763
|
+
case "count-errors": {
|
|
15764
|
+
if (getFlag(flags, "page") !== undefined || getFlag(flags, "perPage") !== undefined) {
|
|
15765
|
+
throw new Error("Error logs now use --cursor and --limit; --page/--perPage are no longer supported.");
|
|
15766
|
+
}
|
|
15767
|
+
const rawTimeFrame = getFlag(flags, "timeFrame");
|
|
15768
|
+
const timeFrame = Object.values(ChartTimeFrame).find((value) => value === rawTimeFrame);
|
|
15769
|
+
if (rawTimeFrame !== undefined && timeFrame === undefined) {
|
|
15770
|
+
throw new Error(`Invalid --timeFrame. Use ${Object.values(ChartTimeFrame).join(", ")}.`);
|
|
15771
|
+
}
|
|
15772
|
+
const filters = {
|
|
14121
15773
|
severity: parseOptionalErrorSeverity(getFlag(flags, "severity")),
|
|
14122
|
-
status: parseOptionalErrorStatus(getFlag(flags, "status"))
|
|
14123
|
-
|
|
15774
|
+
status: parseOptionalErrorStatus(getFlag(flags, "status")),
|
|
15775
|
+
timeFrame
|
|
15776
|
+
};
|
|
15777
|
+
if (cmd === "count-errors") {
|
|
15778
|
+
await countErrors(filters);
|
|
15779
|
+
} else {
|
|
15780
|
+
const direction = getFlag(flags, "direction");
|
|
15781
|
+
if (direction !== undefined && direction !== "forward" && direction !== "backward") {
|
|
15782
|
+
throw new Error("--direction must be forward or backward.");
|
|
15783
|
+
}
|
|
15784
|
+
await getRecentErrors({
|
|
15785
|
+
...filters,
|
|
15786
|
+
cursor: getFlag(flags, "cursor"),
|
|
15787
|
+
limit: parsePositiveIntFlag(getFlag(flags, "limit"), "--limit"),
|
|
15788
|
+
direction
|
|
15789
|
+
});
|
|
15790
|
+
}
|
|
15791
|
+
break;
|
|
15792
|
+
}
|
|
15793
|
+
case "get-error": {
|
|
15794
|
+
const id = positional[0];
|
|
15795
|
+
if (!id)
|
|
15796
|
+
throw new Error("get-error requires <errorId>");
|
|
15797
|
+
await getError(id);
|
|
14124
15798
|
break;
|
|
14125
15799
|
}
|
|
14126
15800
|
case "get-error-metrics": {
|
|
14127
15801
|
await getErrorMetrics();
|
|
14128
15802
|
break;
|
|
14129
15803
|
}
|
|
14130
|
-
case "list-integration-operations":
|
|
14131
|
-
|
|
15804
|
+
case "list-integration-operations":
|
|
15805
|
+
case "count-integration-operations": {
|
|
15806
|
+
rejectRetiredPageFlags(flags);
|
|
15807
|
+
const filters = {
|
|
14132
15808
|
destination: parseCommaSeparatedIds(getFlag(flags, "destination")),
|
|
14133
|
-
page: parsePositiveIntFlag(getFlag(flags, "page"), "--page") ?? 1,
|
|
14134
|
-
perPage: parsePositiveIntFlag(getFlag(flags, "perPage"), "--perPage") ?? 25,
|
|
14135
15809
|
search: getFlag(flags, "search"),
|
|
14136
15810
|
status: parseCommaSeparatedIntegrationOperationStatuses(getFlag(flags, "status"))
|
|
15811
|
+
};
|
|
15812
|
+
if (cmd === "count-integration-operations") {
|
|
15813
|
+
for (const key of ["limit", "cursor", "direction"])
|
|
15814
|
+
if (flags[key] !== undefined)
|
|
15815
|
+
throw new Error(`count-integration-operations does not accept --${key}; it takes filter flags only.`);
|
|
15816
|
+
await countIntegrationOperations(filters);
|
|
15817
|
+
break;
|
|
15818
|
+
}
|
|
15819
|
+
for (const key of ["limit", "cursor", "direction"])
|
|
15820
|
+
rejectBareFlag(flags, key);
|
|
15821
|
+
const cursor = getFlag(flags, "cursor");
|
|
15822
|
+
if (cursor === "" || (cursor?.length ?? 0) > 8192)
|
|
15823
|
+
throw new Error("--cursor must be a non-empty opaque token of at most 8192 characters.");
|
|
15824
|
+
const direction = parseProjectDirection(getFlag(flags, "direction"));
|
|
15825
|
+
if (direction === "backward" && !cursor)
|
|
15826
|
+
throw new Error("--direction backward requires --cursor <token>.");
|
|
15827
|
+
const limitRaw = getFlag(flags, "limit");
|
|
15828
|
+
await listIntegrationOperations({
|
|
15829
|
+
...filters,
|
|
15830
|
+
limit: limitRaw === undefined ? 25 : parseProjectLimit(limitRaw),
|
|
15831
|
+
cursor,
|
|
15832
|
+
direction
|
|
14137
15833
|
});
|
|
14138
15834
|
break;
|
|
14139
15835
|
}
|
|
15836
|
+
case "get-integration-operation": {
|
|
15837
|
+
const operationId = positional[0];
|
|
15838
|
+
if (!operationId) {
|
|
15839
|
+
throw new Error("get-integration-operation requires <operationId>");
|
|
15840
|
+
}
|
|
15841
|
+
await getIntegrationOperation(operationId);
|
|
15842
|
+
break;
|
|
15843
|
+
}
|
|
14140
15844
|
case "retry-integration-operation": {
|
|
14141
15845
|
const operationId = positional[0];
|
|
14142
15846
|
if (!operationId) {
|
|
@@ -14149,13 +15853,153 @@ Waiting for approval\u2026
|
|
|
14149
15853
|
await retryIntegrationOperation(operationId, parseOptionalBoolFlag(flags, "confirmExternalStateReconciled") ?? false, outboundEmailResolution, getFlag(flags, "providerMessageId"));
|
|
14150
15854
|
break;
|
|
14151
15855
|
}
|
|
14152
|
-
case "list-
|
|
14153
|
-
await
|
|
14154
|
-
|
|
14155
|
-
|
|
15856
|
+
case "list-webhook-event-types": {
|
|
15857
|
+
await listWebhookEventTypes();
|
|
15858
|
+
break;
|
|
15859
|
+
}
|
|
15860
|
+
case "list-webhook-endpoints": {
|
|
15861
|
+
await listWebhookEndpoints();
|
|
15862
|
+
break;
|
|
15863
|
+
}
|
|
15864
|
+
case "get-webhook-endpoint": {
|
|
15865
|
+
const id = positional[0];
|
|
15866
|
+
if (!id)
|
|
15867
|
+
throw new Error("get-webhook-endpoint requires <id>");
|
|
15868
|
+
await getWebhookEndpoint(id);
|
|
15869
|
+
break;
|
|
15870
|
+
}
|
|
15871
|
+
case "create-webhook-endpoint": {
|
|
15872
|
+
const name = getFlag(flags, "name");
|
|
15873
|
+
const url = getFlag(flags, "url");
|
|
15874
|
+
const events = parseCommaSeparatedIds(getFlag(flags, "events"));
|
|
15875
|
+
if (!name || !url || !events?.length)
|
|
15876
|
+
throw new Error("create-webhook-endpoint requires --name, --url and --events");
|
|
15877
|
+
await createWebhookEndpoint({
|
|
15878
|
+
name,
|
|
15879
|
+
url,
|
|
15880
|
+
eventPatterns: events,
|
|
15881
|
+
enabled: parseOptionalBoolFlag(flags, "enabled") ?? true
|
|
15882
|
+
});
|
|
15883
|
+
break;
|
|
15884
|
+
}
|
|
15885
|
+
case "update-webhook-endpoint": {
|
|
15886
|
+
const id = positional[0];
|
|
15887
|
+
if (!id)
|
|
15888
|
+
throw new Error("update-webhook-endpoint requires <id>");
|
|
15889
|
+
const events = parseCommaSeparatedIds(getFlag(flags, "events"));
|
|
15890
|
+
await updateWebhookEndpoint({
|
|
15891
|
+
id,
|
|
15892
|
+
name: getFlag(flags, "name"),
|
|
15893
|
+
url: getFlag(flags, "url"),
|
|
15894
|
+
eventPatterns: events?.length ? events : undefined,
|
|
15895
|
+
enabled: parseOptionalBoolFlag(flags, "enabled")
|
|
15896
|
+
});
|
|
15897
|
+
break;
|
|
15898
|
+
}
|
|
15899
|
+
case "delete-webhook-endpoint": {
|
|
15900
|
+
const id = positional[0];
|
|
15901
|
+
if (!id)
|
|
15902
|
+
throw new Error("delete-webhook-endpoint requires <id>");
|
|
15903
|
+
await deleteWebhookEndpoint(id);
|
|
15904
|
+
break;
|
|
15905
|
+
}
|
|
15906
|
+
case "rotate-webhook-secret": {
|
|
15907
|
+
const id = positional[0];
|
|
15908
|
+
if (!id)
|
|
15909
|
+
throw new Error("rotate-webhook-secret requires <id>");
|
|
15910
|
+
const ttl = getFlag(flags, "previousSecretTtlHours");
|
|
15911
|
+
await rotateWebhookSecret({
|
|
15912
|
+
id,
|
|
15913
|
+
previousSecretTtlHours: ttl === undefined ? undefined : Number.parseInt(ttl, 10)
|
|
15914
|
+
});
|
|
15915
|
+
break;
|
|
15916
|
+
}
|
|
15917
|
+
case "send-webhook-test-event": {
|
|
15918
|
+
const id = positional[0];
|
|
15919
|
+
if (!id)
|
|
15920
|
+
throw new Error("send-webhook-test-event requires <id>");
|
|
15921
|
+
await sendWebhookTestEvent(id);
|
|
15922
|
+
break;
|
|
15923
|
+
}
|
|
15924
|
+
case "list-webhook-deliveries": {
|
|
15925
|
+
const status = getFlag(flags, "status");
|
|
15926
|
+
if (status && status !== "PENDING" && status !== "SUCCEEDED" && status !== "FAILED")
|
|
15927
|
+
throw new Error("--status must be PENDING, SUCCEEDED or FAILED");
|
|
15928
|
+
await listWebhookDeliveries({
|
|
15929
|
+
endpointId: getFlag(flags, "endpointId"),
|
|
15930
|
+
status,
|
|
15931
|
+
eventType: getFlag(flags, "eventType"),
|
|
15932
|
+
cursor: getFlag(flags, "cursor"),
|
|
15933
|
+
limit: parsePositiveIntFlag(getFlag(flags, "limit"), "--limit")
|
|
14156
15934
|
});
|
|
14157
15935
|
break;
|
|
14158
15936
|
}
|
|
15937
|
+
case "get-webhook-delivery": {
|
|
15938
|
+
const id = positional[0];
|
|
15939
|
+
if (!id)
|
|
15940
|
+
throw new Error("get-webhook-delivery requires <id>");
|
|
15941
|
+
await getWebhookDelivery(id);
|
|
15942
|
+
break;
|
|
15943
|
+
}
|
|
15944
|
+
case "replay-webhook-delivery": {
|
|
15945
|
+
const id = positional[0];
|
|
15946
|
+
if (!id)
|
|
15947
|
+
throw new Error("replay-webhook-delivery requires <id>");
|
|
15948
|
+
await replayWebhookDelivery(id);
|
|
15949
|
+
break;
|
|
15950
|
+
}
|
|
15951
|
+
case "reconcile-resource-operation": {
|
|
15952
|
+
const operationId = positional[0];
|
|
15953
|
+
if (!operationId) {
|
|
15954
|
+
throw new Error("reconcile-resource-operation requires <operationId>");
|
|
15955
|
+
}
|
|
15956
|
+
await reconcileResourceOperation(operationId);
|
|
15957
|
+
break;
|
|
15958
|
+
}
|
|
15959
|
+
case "list-inbound-sources":
|
|
15960
|
+
case "count-inbound-sources": {
|
|
15961
|
+
if (flags.page !== undefined || flags.perPage !== undefined)
|
|
15962
|
+
throw new Error("Inbound sources now use --limit/--cursor/--direction; --page/--perPage are no longer supported.");
|
|
15963
|
+
for (const key of ["search", "processingMode", "cursor", "direction"]) {
|
|
15964
|
+
if (flags[key] === true)
|
|
15965
|
+
throw new Error(`--${key} requires a value.`);
|
|
15966
|
+
}
|
|
15967
|
+
const enabled = flags.processingEnabled;
|
|
15968
|
+
if (enabled !== undefined && enabled !== "true" && enabled !== "false")
|
|
15969
|
+
throw new Error("--processingEnabled must be true or false.");
|
|
15970
|
+
const mode = getFlag(flags, "processingMode");
|
|
15971
|
+
const processingMode = Object.values(InboundProcessingMode).find((value) => value === mode);
|
|
15972
|
+
if (mode !== undefined && processingMode === undefined)
|
|
15973
|
+
throw new Error("Invalid --processingMode. Use ACTIVE, COLLECT_ONLY or SHADOW.");
|
|
15974
|
+
const filters = {
|
|
15975
|
+
search: getFlag(flags, "search"),
|
|
15976
|
+
processingEnabled: enabled === undefined ? undefined : enabled === "true",
|
|
15977
|
+
processingMode
|
|
15978
|
+
};
|
|
15979
|
+
if (cmd === "count-inbound-sources") {
|
|
15980
|
+
if (["limit", "cursor", "direction"].some((key) => flags[key] !== undefined))
|
|
15981
|
+
throw new Error("Source counts accept filters only, not pagination flags.");
|
|
15982
|
+
await countInboundSources(filters);
|
|
15983
|
+
} else {
|
|
15984
|
+
const direction = getFlag(flags, "direction") ?? "forward";
|
|
15985
|
+
if (direction !== "forward" && direction !== "backward")
|
|
15986
|
+
throw new Error("--direction must be forward or backward.");
|
|
15987
|
+
const cursor = getFlag(flags, "cursor");
|
|
15988
|
+
if (direction === "backward" && !cursor)
|
|
15989
|
+
throw new Error("Backward source pagination requires --cursor.");
|
|
15990
|
+
const rawLimit = flags.limit;
|
|
15991
|
+
const limit = rawLimit === undefined ? 25 : Number(rawLimit);
|
|
15992
|
+
if (rawLimit === true || !Number.isInteger(limit) || limit < 1 || limit > 100)
|
|
15993
|
+
throw new Error("--limit must be an integer between 1 and 100.");
|
|
15994
|
+
await listInboundSources({
|
|
15995
|
+
...filters,
|
|
15996
|
+
cursor,
|
|
15997
|
+
direction,
|
|
15998
|
+
limit
|
|
15999
|
+
});
|
|
16000
|
+
}
|
|
16001
|
+
break;
|
|
16002
|
+
}
|
|
14159
16003
|
case "create-inbound-source": {
|
|
14160
16004
|
const name = getFlag(flags, "name");
|
|
14161
16005
|
const externalSourceId = getFlag(flags, "formId");
|
|
@@ -14182,13 +16026,20 @@ Waiting for approval\u2026
|
|
|
14182
16026
|
break;
|
|
14183
16027
|
}
|
|
14184
16028
|
case "list-inbound-submissions": {
|
|
16029
|
+
if (getFlag(flags, "page") !== undefined || getFlag(flags, "perPage") !== undefined) {
|
|
16030
|
+
throw new Error("Inbound submissions now use --limit and --cursor; --page/--perPage are no longer supported.");
|
|
16031
|
+
}
|
|
14185
16032
|
await listInboundSubmissions({
|
|
14186
|
-
|
|
14187
|
-
|
|
16033
|
+
cursor: getFlag(flags, "cursor"),
|
|
16034
|
+
limit: parsePositiveIntFlag(getFlag(flags, "limit"), "--limit") ?? 25,
|
|
14188
16035
|
sourceId: getFlag(flags, "sourceId")
|
|
14189
16036
|
});
|
|
14190
16037
|
break;
|
|
14191
16038
|
}
|
|
16039
|
+
case "count-inbound-submissions": {
|
|
16040
|
+
await countInboundSubmissions({ sourceId: getFlag(flags, "sourceId") });
|
|
16041
|
+
break;
|
|
16042
|
+
}
|
|
14192
16043
|
case "get-inbound-submission": {
|
|
14193
16044
|
const submissionId = positional[0];
|
|
14194
16045
|
if (!submissionId) {
|