@warmhub/cli 0.44.0 → 0.45.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/wh.js +248 -38
- package/package.json +1 -1
package/dist/wh.js
CHANGED
|
@@ -19358,7 +19358,7 @@ function findSystemComponent(componentId) {
|
|
|
19358
19358
|
// ../../packages/sdk-ts/package.json
|
|
19359
19359
|
var package_default = {
|
|
19360
19360
|
name: "@warmhub/sdk-ts",
|
|
19361
|
-
version: "0.
|
|
19361
|
+
version: "0.44.1",
|
|
19362
19362
|
private: false,
|
|
19363
19363
|
type: "module",
|
|
19364
19364
|
homepage: "https://docs.warmhub.ai",
|
|
@@ -19852,13 +19852,15 @@ class WarmHubError extends Error {
|
|
|
19852
19852
|
status;
|
|
19853
19853
|
hint;
|
|
19854
19854
|
retryAfter;
|
|
19855
|
-
|
|
19855
|
+
backendCode;
|
|
19856
|
+
constructor(code, message, status, hint, retryAfter, backendCode) {
|
|
19856
19857
|
super(message);
|
|
19857
19858
|
this.name = "WarmHubError";
|
|
19858
19859
|
this.code = code;
|
|
19859
19860
|
this.status = status;
|
|
19860
19861
|
this.hint = hint;
|
|
19861
19862
|
this.retryAfter = retryAfter;
|
|
19863
|
+
this.backendCode = backendCode;
|
|
19862
19864
|
}
|
|
19863
19865
|
get kind() {
|
|
19864
19866
|
return this.code;
|
|
@@ -19881,13 +19883,14 @@ function toWarmHubError(error) {
|
|
|
19881
19883
|
return error.cause;
|
|
19882
19884
|
}
|
|
19883
19885
|
const data = error.data;
|
|
19886
|
+
const wireCode = data?.warmhub?.code;
|
|
19884
19887
|
const message = data?.warmhub?.message ?? sanitizeErrorMessage(error.message);
|
|
19885
|
-
return new WarmHubError(
|
|
19888
|
+
return new WarmHubError(wireCode ?? "BACKEND", message, data?.warmhub?.status, data?.warmhub?.hint, data?.warmhub?.retryAfter, wireCode);
|
|
19886
19889
|
}
|
|
19887
19890
|
if (error instanceof Error) {
|
|
19888
19891
|
const warmhubLike = error;
|
|
19889
19892
|
if (error.name === "WarmHubError" && typeof warmhubLike.code === "string") {
|
|
19890
|
-
return new WarmHubError(warmhubLike.code, sanitizeErrorMessage(error.message), typeof warmhubLike.status === "number" ? warmhubLike.status : undefined, typeof warmhubLike.hint === "string" ? warmhubLike.hint : undefined, typeof warmhubLike.retryAfter === "number" ? warmhubLike.retryAfter : undefined);
|
|
19893
|
+
return new WarmHubError(warmhubLike.code, sanitizeErrorMessage(error.message), typeof warmhubLike.status === "number" ? warmhubLike.status : undefined, typeof warmhubLike.hint === "string" ? warmhubLike.hint : undefined, typeof warmhubLike.retryAfter === "number" ? warmhubLike.retryAfter : undefined, typeof warmhubLike.backendCode === "string" ? warmhubLike.backendCode : undefined);
|
|
19891
19894
|
}
|
|
19892
19895
|
if (error.name === "AbortError") {
|
|
19893
19896
|
return new WarmHubError("CANCELLED", error.message);
|
|
@@ -20547,6 +20550,18 @@ class WarmHubClient {
|
|
|
20547
20550
|
} catch (error) {
|
|
20548
20551
|
throw toWarmHubError(error);
|
|
20549
20552
|
}
|
|
20553
|
+
},
|
|
20554
|
+
index: {
|
|
20555
|
+
describe: async (orgName, repoName) => {
|
|
20556
|
+
try {
|
|
20557
|
+
return await this.trpc.repo.index.describe.query({
|
|
20558
|
+
orgName,
|
|
20559
|
+
repoName
|
|
20560
|
+
});
|
|
20561
|
+
} catch (error) {
|
|
20562
|
+
throw toWarmHubError(error);
|
|
20563
|
+
}
|
|
20564
|
+
}
|
|
20550
20565
|
}
|
|
20551
20566
|
};
|
|
20552
20567
|
shape = {
|
|
@@ -20869,7 +20884,8 @@ class WarmHubClient {
|
|
|
20869
20884
|
cursor: opts?.cursor,
|
|
20870
20885
|
componentId: opts?.componentId,
|
|
20871
20886
|
excludeComponents: opts?.excludeComponents,
|
|
20872
|
-
excludeInfraShapes: opts?.excludeInfraShapes
|
|
20887
|
+
excludeInfraShapes: opts?.excludeInfraShapes,
|
|
20888
|
+
where: opts?.where
|
|
20873
20889
|
});
|
|
20874
20890
|
} catch (error) {
|
|
20875
20891
|
throw toWarmHubError(error);
|
|
@@ -21002,7 +21018,8 @@ class WarmHubClient {
|
|
|
21002
21018
|
depth: opts?.depth,
|
|
21003
21019
|
resolveCollections: opts?.resolveCollections,
|
|
21004
21020
|
limit: opts?.limit,
|
|
21005
|
-
cursor: opts?.cursor
|
|
21021
|
+
cursor: opts?.cursor,
|
|
21022
|
+
where: opts?.where
|
|
21006
21023
|
});
|
|
21007
21024
|
} catch (error) {
|
|
21008
21025
|
throw toWarmHubError(error);
|
|
@@ -21031,7 +21048,8 @@ class WarmHubClient {
|
|
|
21031
21048
|
cursor: opts?.cursor,
|
|
21032
21049
|
componentId: opts?.componentId,
|
|
21033
21050
|
excludeComponents: opts?.excludeComponents,
|
|
21034
|
-
excludeInfraShapes: opts?.excludeInfraShapes
|
|
21051
|
+
excludeInfraShapes: opts?.excludeInfraShapes,
|
|
21052
|
+
where: opts?.where
|
|
21035
21053
|
});
|
|
21036
21054
|
} catch (error) {
|
|
21037
21055
|
throw toWarmHubError(error);
|
|
@@ -21082,7 +21100,8 @@ class WarmHubClient {
|
|
|
21082
21100
|
resolveCollections: opts?.resolveCollections,
|
|
21083
21101
|
componentId: opts?.componentId,
|
|
21084
21102
|
excludeComponents: opts?.excludeComponents,
|
|
21085
|
-
excludeInfraShapes: opts?.excludeInfraShapes
|
|
21103
|
+
excludeInfraShapes: opts?.excludeInfraShapes,
|
|
21104
|
+
where: opts?.where
|
|
21086
21105
|
});
|
|
21087
21106
|
} catch (error) {
|
|
21088
21107
|
throw toWarmHubError(error);
|
|
@@ -21120,7 +21139,8 @@ class WarmHubClient {
|
|
|
21120
21139
|
dataMode: opts?.dataMode,
|
|
21121
21140
|
limit: opts?.limit,
|
|
21122
21141
|
cursor: opts?.cursor,
|
|
21123
|
-
includeRetracted: opts?.includeRetracted
|
|
21142
|
+
includeRetracted: opts?.includeRetracted,
|
|
21143
|
+
where: opts?.where
|
|
21124
21144
|
}), onUpdate);
|
|
21125
21145
|
},
|
|
21126
21146
|
thingHistory: async (orgName, repoName, opts, onUpdate) => {
|
|
@@ -21457,6 +21477,7 @@ class WarmHubClient {
|
|
|
21457
21477
|
if (!response.ok) {
|
|
21458
21478
|
let message = `Request failed with status ${response.status}`;
|
|
21459
21479
|
let code = httpStatusToWarmHubCode(response.status);
|
|
21480
|
+
let backendCode;
|
|
21460
21481
|
let hint;
|
|
21461
21482
|
let retryAfter;
|
|
21462
21483
|
try {
|
|
@@ -21466,6 +21487,7 @@ class WarmHubClient {
|
|
|
21466
21487
|
}
|
|
21467
21488
|
if (typeof body.error?.code === "string") {
|
|
21468
21489
|
code = body.error.code;
|
|
21490
|
+
backendCode = body.error.code;
|
|
21469
21491
|
}
|
|
21470
21492
|
if (typeof body.error?.hint === "string") {
|
|
21471
21493
|
hint = body.error.hint;
|
|
@@ -21474,7 +21496,7 @@ class WarmHubClient {
|
|
|
21474
21496
|
retryAfter = body.error.retryAfter;
|
|
21475
21497
|
}
|
|
21476
21498
|
} catch {}
|
|
21477
|
-
throw new WarmHubError(code, message, response.status, hint, retryAfter);
|
|
21499
|
+
throw new WarmHubError(code, message, response.status, hint, retryAfter, backendCode);
|
|
21478
21500
|
}
|
|
21479
21501
|
return response;
|
|
21480
21502
|
}
|
|
@@ -21592,13 +21614,15 @@ class CliError extends Error {
|
|
|
21592
21614
|
kind;
|
|
21593
21615
|
cause;
|
|
21594
21616
|
hint;
|
|
21617
|
+
backendCode;
|
|
21595
21618
|
context;
|
|
21596
|
-
constructor(code, kind, message, cause, hint, context) {
|
|
21619
|
+
constructor(code, kind, message, cause, hint, context, backendCode) {
|
|
21597
21620
|
super(message);
|
|
21598
21621
|
this.code = code;
|
|
21599
21622
|
this.kind = kind;
|
|
21600
21623
|
this.cause = cause;
|
|
21601
21624
|
this.hint = hint;
|
|
21625
|
+
this.backendCode = backendCode;
|
|
21602
21626
|
this.context = context;
|
|
21603
21627
|
}
|
|
21604
21628
|
}
|
|
@@ -21624,24 +21648,33 @@ function conflictHint(message) {
|
|
|
21624
21648
|
}
|
|
21625
21649
|
return "Resolve the conflicting existing state and try again.";
|
|
21626
21650
|
}
|
|
21651
|
+
function isFieldIndexErrorCode(code) {
|
|
21652
|
+
return code === "FIELD_INDEX_UNAVAILABLE" || code === "FIELD_NOT_INDEXABLE" || code === "FIELD_TYPE_AMBIGUOUS";
|
|
21653
|
+
}
|
|
21654
|
+
function fromWh(exit, kind, err, hint = err.hint) {
|
|
21655
|
+
return new CliError(exit, kind, err.message, err, hint, undefined, err.backendCode);
|
|
21656
|
+
}
|
|
21627
21657
|
function toCliError(err) {
|
|
21628
21658
|
if (err instanceof CliError)
|
|
21629
21659
|
return err;
|
|
21630
21660
|
if (err instanceof WarmHubError) {
|
|
21631
21661
|
if (err.kind === "VALIDATION_ERROR" || err.kind === "SHAPE_MISMATCH" || err.kind === "NOT_FOUND") {
|
|
21632
|
-
return
|
|
21662
|
+
return fromWh(2 /* UserInput */, "USER_INPUT", err);
|
|
21633
21663
|
}
|
|
21634
21664
|
if (err.kind === "UNAUTHENTICATED" || err.kind === "FORBIDDEN") {
|
|
21635
|
-
|
|
21636
|
-
|
|
21665
|
+
return fromWh(3 /* Config */, "AUTH", err, err.hint ?? unauthenticatedHint(err.message));
|
|
21666
|
+
}
|
|
21667
|
+
if (isFieldIndexErrorCode(err.code)) {
|
|
21668
|
+
const exit = err.code === "FIELD_NOT_INDEXABLE" ? 2 /* UserInput */ : 4 /* Backend */;
|
|
21669
|
+
return fromWh(exit, err.code, err);
|
|
21637
21670
|
}
|
|
21638
21671
|
if ((err.code === "CONFLICT" || err.code === "ARCHIVED") && err.status === undefined) {
|
|
21639
|
-
return
|
|
21672
|
+
return fromWh(2 /* UserInput */, "CONFLICT", err, err.hint ?? conflictHint(err.message));
|
|
21640
21673
|
}
|
|
21641
21674
|
if (err.status) {
|
|
21642
|
-
return
|
|
21675
|
+
return fromWh(4 /* Backend */, "BACKEND", err);
|
|
21643
21676
|
}
|
|
21644
|
-
return
|
|
21677
|
+
return fromWh(4 /* Backend */, "BACKEND", err, err.hint ?? "Check that the API URL and backend are reachable.");
|
|
21645
21678
|
}
|
|
21646
21679
|
if (err instanceof TypeError && err.message.includes("fetch")) {
|
|
21647
21680
|
return new CliError(4 /* Backend */, "BACKEND", "Network error connecting to backend", err, "Check WARMHUB_API_URL or --api-url.");
|
|
@@ -21738,6 +21771,30 @@ function generateSuggestions(code, message, context) {
|
|
|
21738
21771
|
});
|
|
21739
21772
|
}
|
|
21740
21773
|
}
|
|
21774
|
+
if (code === "FIELD_NOT_INDEXABLE") {
|
|
21775
|
+
suggestions.push({
|
|
21776
|
+
action: "Inspect indexed field state for the repo",
|
|
21777
|
+
command: "wh repo describe --indexed-fields"
|
|
21778
|
+
});
|
|
21779
|
+
suggestions.push({
|
|
21780
|
+
action: "Use a shape-declared, indexable scalar field in --where"
|
|
21781
|
+
});
|
|
21782
|
+
}
|
|
21783
|
+
if (code === "FIELD_INDEX_UNAVAILABLE") {
|
|
21784
|
+
suggestions.push({
|
|
21785
|
+
action: "Retry after the field index finishes building"
|
|
21786
|
+
});
|
|
21787
|
+
suggestions.push({
|
|
21788
|
+
action: "Inspect indexed field state for the repo",
|
|
21789
|
+
command: "wh repo describe --indexed-fields"
|
|
21790
|
+
});
|
|
21791
|
+
}
|
|
21792
|
+
if (code === "FIELD_TYPE_AMBIGUOUS") {
|
|
21793
|
+
suggestions.push({
|
|
21794
|
+
action: "Inspect indexed field state for heterogeneous field types",
|
|
21795
|
+
command: "wh repo describe --indexed-fields"
|
|
21796
|
+
});
|
|
21797
|
+
}
|
|
21741
21798
|
if (code === "AUTH") {
|
|
21742
21799
|
suggestions.push({
|
|
21743
21800
|
action: "Re-authenticate",
|
|
@@ -21771,6 +21828,11 @@ function shouldLogToErrorTier(err) {
|
|
|
21771
21828
|
case "AUTH":
|
|
21772
21829
|
case "UNKNOWN":
|
|
21773
21830
|
return true;
|
|
21831
|
+
case "FIELD_NOT_INDEXABLE":
|
|
21832
|
+
return false;
|
|
21833
|
+
case "FIELD_INDEX_UNAVAILABLE":
|
|
21834
|
+
case "FIELD_TYPE_AMBIGUOUS":
|
|
21835
|
+
return true;
|
|
21774
21836
|
case "BACKEND": {
|
|
21775
21837
|
const status = err.cause?.status;
|
|
21776
21838
|
if (typeof status === "number" && status >= 400 && status < 500) {
|
|
@@ -21787,7 +21849,7 @@ function cliErrorFromOpFailure(failure) {
|
|
|
21787
21849
|
const message = failure.error?.message ?? `Operation on "${failure.name}" failed`;
|
|
21788
21850
|
const exit = code === "FORBIDDEN" || code === "UNAUTHENTICATED" ? 5 /* Auth */ : code === "VALIDATION_ERROR" || code === "SHAPE_MISMATCH" || code === "NOT_FOUND" || code === "KIND_MISMATCH" || code === "ALREADY_RETRACTED" || code === "CONFLICT" ? 2 /* UserInput */ : 4 /* Backend */;
|
|
21789
21851
|
const kind = exit === 5 /* Auth */ ? "AUTH" : exit === 2 /* UserInput */ ? code === "CONFLICT" ? "CONFLICT" : "USER_INPUT" : "BACKEND";
|
|
21790
|
-
return new CliError(exit, kind, message);
|
|
21852
|
+
return new CliError(exit, kind, message, undefined, undefined, undefined, failure.error?.code);
|
|
21791
21853
|
}
|
|
21792
21854
|
function cliErrorFromAllFailed(failures) {
|
|
21793
21855
|
const exitPriority = (failure) => {
|
|
@@ -21826,6 +21888,7 @@ function printCliError(err, errWriter, opts = {}) {
|
|
|
21826
21888
|
const envelope = {
|
|
21827
21889
|
error: {
|
|
21828
21890
|
code: err.kind,
|
|
21891
|
+
...err.backendCode ? { backendCode: err.backendCode } : {},
|
|
21829
21892
|
message: err.message,
|
|
21830
21893
|
...err.hint ? { hint: err.hint } : {},
|
|
21831
21894
|
...suggestions.length > 0 ? { suggestions } : {},
|
|
@@ -24533,10 +24596,64 @@ async function readContentInput(filePath, inline, stdinStream) {
|
|
|
24533
24596
|
function usageError(usage, example) {
|
|
24534
24597
|
throw new CliError(2 /* UserInput */, "USER_INPUT", usage, undefined, `Example: ${example}`);
|
|
24535
24598
|
}
|
|
24599
|
+
var WHERE_USAGE_HINT = 'Example: --where state=NC --where "employees>=100" --where "state?"';
|
|
24600
|
+
function requireWhereFieldPath(raw, fieldPath) {
|
|
24601
|
+
const normalized = fieldPath.trim();
|
|
24602
|
+
if (!normalized) {
|
|
24603
|
+
throw new CliError(2 /* UserInput */, "USER_INPUT", `Malformed --where predicate: "${raw}". Field path cannot be empty.`, undefined, WHERE_USAGE_HINT);
|
|
24604
|
+
}
|
|
24605
|
+
return normalized;
|
|
24606
|
+
}
|
|
24607
|
+
function parseWhereFlag(raw) {
|
|
24608
|
+
const opMatch = raw.match(/^(.+?)\s*(>=|<=|!=|=|>|<)\s*(.*)$/);
|
|
24609
|
+
if (opMatch) {
|
|
24610
|
+
const fieldPath = requireWhereFieldPath(raw, opMatch[1]);
|
|
24611
|
+
const opStr = opMatch[2];
|
|
24612
|
+
const rhsStr = (opMatch[3] ?? "").trim();
|
|
24613
|
+
const op = opStr === "=" ? "eq" : opStr === "!=" ? "ne" : opStr === ">=" ? "gte" : opStr === "<=" ? "lte" : opStr === ">" ? "gt" : "lt";
|
|
24614
|
+
const rhs = coerceValue(rhsStr);
|
|
24615
|
+
return { fieldPath, op, rhs };
|
|
24616
|
+
}
|
|
24617
|
+
const inMatch = raw.match(/^(.+?)\s+in:\[(.*)?\]$/);
|
|
24618
|
+
if (inMatch) {
|
|
24619
|
+
const fieldPath = requireWhereFieldPath(raw, inMatch[1]);
|
|
24620
|
+
const valueStr = inMatch[2] ?? "";
|
|
24621
|
+
if (valueStr.trim() === "") {
|
|
24622
|
+
throw new CliError(2 /* UserInput */, "USER_INPUT", `Invalid --where "${raw}": in:[] requires at least one value`, undefined, 'Example: --where "state in:[NC,VA]"');
|
|
24623
|
+
}
|
|
24624
|
+
const rhs = valueStr.split(",").map((v) => coerceValue(v.trim()));
|
|
24625
|
+
if (rhs.length > MAX_WHERE_IN_VALUES) {
|
|
24626
|
+
throw new CliError(2 /* UserInput */, "USER_INPUT", `Invalid --where "${raw}": in:[...] supports at most ${MAX_WHERE_IN_VALUES} values`, undefined, `Split the query into smaller batches of at most ${MAX_WHERE_IN_VALUES} values.`);
|
|
24627
|
+
}
|
|
24628
|
+
return { fieldPath, op: "in", rhs };
|
|
24629
|
+
}
|
|
24630
|
+
const prefixMatch = raw.match(/^(.+?)~(.+)$/);
|
|
24631
|
+
if (prefixMatch) {
|
|
24632
|
+
const fieldPath = requireWhereFieldPath(raw, prefixMatch[1]);
|
|
24633
|
+
const rhs = coerceValue(prefixMatch[2].replace(/\*$/, ""));
|
|
24634
|
+
return { fieldPath, op: "prefix", rhs };
|
|
24635
|
+
}
|
|
24636
|
+
if (raw.endsWith("?")) {
|
|
24637
|
+
const fieldPath = requireWhereFieldPath(raw, raw.slice(0, -1));
|
|
24638
|
+
return { fieldPath, op: "exists" };
|
|
24639
|
+
}
|
|
24640
|
+
throw new CliError(2 /* UserInput */, "USER_INPUT", `Malformed --where predicate: "${raw}". Supported operators: =, !=, >, >=, <, <=, ~, in:[...], ?`, undefined, WHERE_USAGE_HINT);
|
|
24641
|
+
}
|
|
24642
|
+
function coerceValue(s) {
|
|
24643
|
+
if (s.startsWith('"') && s.endsWith('"') || s.startsWith("'") && s.endsWith("'")) {
|
|
24644
|
+
return s.slice(1, -1);
|
|
24645
|
+
}
|
|
24646
|
+
if (s === "true")
|
|
24647
|
+
return true;
|
|
24648
|
+
if (s === "false")
|
|
24649
|
+
return false;
|
|
24650
|
+
return s;
|
|
24651
|
+
}
|
|
24536
24652
|
var DEFAULT_PAGE_LIMIT = 50;
|
|
24537
24653
|
var DEFAULT_SEARCH_LIMIT = 25;
|
|
24538
24654
|
var MAX_PAGE_LIMIT = 500;
|
|
24539
24655
|
var AUTO_PAGE_LIMIT = MAX_PAGE_LIMIT;
|
|
24656
|
+
var MAX_WHERE_IN_VALUES = 1000;
|
|
24540
24657
|
async function handleCount(ctx, org, repo, opts) {
|
|
24541
24658
|
const result = await ctx.client.thing.count(org, repo, opts);
|
|
24542
24659
|
writeOutput(ctx, result, () => ctx.out(`${result.count}`));
|
|
@@ -24778,6 +24895,10 @@ var headFlags = {
|
|
|
24778
24895
|
}),
|
|
24779
24896
|
"exclude-components": flag.boolean({
|
|
24780
24897
|
description: "Exclude component-owned things from results"
|
|
24898
|
+
}),
|
|
24899
|
+
where: flag.string({
|
|
24900
|
+
multiple: true,
|
|
24901
|
+
description: `Field-value WHERE predicate (repeatable). Syntax: field=val, field>=val, field~prefix*, field in:[a,b] (max ${MAX_WHERE_IN_VALUES} values), field? (exists). Predicates are served by the typed field index; unservable fields return a machine-readable field-index error instead of scanning JSONB bodies.`
|
|
24781
24902
|
})
|
|
24782
24903
|
};
|
|
24783
24904
|
var handleHead = async (ctx, { flags, args }) => {
|
|
@@ -24790,6 +24911,8 @@ var handleHead = async (ctx, { flags, args }) => {
|
|
|
24790
24911
|
const match = flags.match;
|
|
24791
24912
|
const count = flags.count;
|
|
24792
24913
|
const includeRetracted = flags["include-retracted"];
|
|
24914
|
+
const whereRaw = flags.where ?? [];
|
|
24915
|
+
const where = whereRaw.map(parseWhereFlag);
|
|
24793
24916
|
if (count) {
|
|
24794
24917
|
if (cursor || all || limit || ctx.liveMode) {
|
|
24795
24918
|
usageError("Usage: wh thing list --count [--shape SHAPE] [--kind KIND] [--match PATTERN]", "wh thing list --shape Player --count");
|
|
@@ -24804,7 +24927,8 @@ var handleHead = async (ctx, { flags, args }) => {
|
|
|
24804
24927
|
includeRetracted,
|
|
24805
24928
|
componentId: componentId2,
|
|
24806
24929
|
excludeComponents: strictExclude2,
|
|
24807
|
-
excludeInfraShapes: !strictExclude2 && !shape
|
|
24930
|
+
excludeInfraShapes: !strictExclude2 && !shape,
|
|
24931
|
+
where: where.length > 0 ? where : undefined
|
|
24808
24932
|
});
|
|
24809
24933
|
}
|
|
24810
24934
|
if (cursor && !limit) {
|
|
@@ -24830,7 +24954,8 @@ var handleHead = async (ctx, { flags, args }) => {
|
|
|
24830
24954
|
cursor,
|
|
24831
24955
|
componentId,
|
|
24832
24956
|
excludeComponents,
|
|
24833
|
-
excludeInfraShapes
|
|
24957
|
+
excludeInfraShapes,
|
|
24958
|
+
where: where.length > 0 ? where : undefined
|
|
24834
24959
|
};
|
|
24835
24960
|
if (ctx.liveMode) {
|
|
24836
24961
|
await runLive({
|
|
@@ -24860,7 +24985,8 @@ var handleHead = async (ctx, { flags, args }) => {
|
|
|
24860
24985
|
cursor,
|
|
24861
24986
|
componentId,
|
|
24862
24987
|
excludeComponents,
|
|
24863
|
-
excludeInfraShapes
|
|
24988
|
+
excludeInfraShapes,
|
|
24989
|
+
where: where.length > 0 ? where : undefined
|
|
24864
24990
|
}) : await ctx.client.thing.head(org, repo, {
|
|
24865
24991
|
shape,
|
|
24866
24992
|
kind,
|
|
@@ -24870,7 +24996,8 @@ var handleHead = async (ctx, { flags, args }) => {
|
|
|
24870
24996
|
cursor,
|
|
24871
24997
|
componentId,
|
|
24872
24998
|
excludeComponents,
|
|
24873
|
-
excludeInfraShapes
|
|
24999
|
+
excludeInfraShapes,
|
|
25000
|
+
where: where.length > 0 ? where : undefined
|
|
24874
25001
|
});
|
|
24875
25002
|
writeOutput(ctx, result, () => renderHead(ctx.out, ctx.colors, ctx.chars, result, org, repo, shape, kind));
|
|
24876
25003
|
};
|
|
@@ -24887,7 +25014,8 @@ async function fetchAllHeadPages(ctx, org, repo, opts) {
|
|
|
24887
25014
|
cursor,
|
|
24888
25015
|
componentId: opts.componentId,
|
|
24889
25016
|
excludeComponents: opts.excludeComponents,
|
|
24890
|
-
excludeInfraShapes: opts.excludeInfraShapes
|
|
25017
|
+
excludeInfraShapes: opts.excludeInfraShapes,
|
|
25018
|
+
where: opts.where
|
|
24891
25019
|
});
|
|
24892
25020
|
items.push(...page.items ?? []);
|
|
24893
25021
|
if (!page.nextCursor)
|
|
@@ -25333,6 +25461,10 @@ var queryFlags = {
|
|
|
25333
25461
|
}),
|
|
25334
25462
|
"exclude-components": flag.boolean({
|
|
25335
25463
|
description: "Exclude component-owned things from results"
|
|
25464
|
+
}),
|
|
25465
|
+
where: flag.string({
|
|
25466
|
+
multiple: true,
|
|
25467
|
+
description: `Field-value WHERE predicate (repeatable). Syntax: field=val, field>=val, field~prefix*, field in:[a,b] (max ${MAX_WHERE_IN_VALUES} values), field? (exists). Predicates are served by the typed field index; unservable fields return a machine-readable field-index error instead of scanning JSONB bodies.`
|
|
25336
25468
|
})
|
|
25337
25469
|
};
|
|
25338
25470
|
var handleQuery = async (ctx, { flags }) => {
|
|
@@ -25354,6 +25486,8 @@ var handleQuery = async (ctx, { flags }) => {
|
|
|
25354
25486
|
const excludeComponents = strictExclude;
|
|
25355
25487
|
const excludeInfraShapes = !strictExclude && !hasShape;
|
|
25356
25488
|
const c = ctx.colors;
|
|
25489
|
+
const whereRaw = flags.where ?? [];
|
|
25490
|
+
const where = whereRaw.map(parseWhereFlag);
|
|
25357
25491
|
if (count) {
|
|
25358
25492
|
if (cursor || all || limit || ctx.liveMode) {
|
|
25359
25493
|
usageError("Usage: wh thing query --count [--shape SHAPE] [--about WREF] [--kind KIND] [--match PATTERN]", "wh thing query --kind assertion --about Player/alice --count");
|
|
@@ -25367,7 +25501,8 @@ var handleQuery = async (ctx, { flags }) => {
|
|
|
25367
25501
|
resolveCollections,
|
|
25368
25502
|
componentId,
|
|
25369
25503
|
excludeComponents,
|
|
25370
|
-
excludeInfraShapes
|
|
25504
|
+
excludeInfraShapes,
|
|
25505
|
+
where: where.length > 0 ? where : undefined
|
|
25371
25506
|
});
|
|
25372
25507
|
}
|
|
25373
25508
|
if (cursor && !limit) {
|
|
@@ -25389,7 +25524,8 @@ var handleQuery = async (ctx, { flags }) => {
|
|
|
25389
25524
|
cursor,
|
|
25390
25525
|
componentId,
|
|
25391
25526
|
excludeComponents,
|
|
25392
|
-
excludeInfraShapes
|
|
25527
|
+
excludeInfraShapes,
|
|
25528
|
+
where: where.length > 0 ? where : undefined
|
|
25393
25529
|
};
|
|
25394
25530
|
if (ctx.liveMode) {
|
|
25395
25531
|
await runLive({
|
|
@@ -25421,7 +25557,8 @@ var handleQuery = async (ctx, { flags }) => {
|
|
|
25421
25557
|
cursor,
|
|
25422
25558
|
componentId,
|
|
25423
25559
|
excludeComponents,
|
|
25424
|
-
excludeInfraShapes
|
|
25560
|
+
excludeInfraShapes,
|
|
25561
|
+
where: where.length > 0 ? where : undefined
|
|
25425
25562
|
}) : await ctx.client.thing.query(org, repo, {
|
|
25426
25563
|
shape,
|
|
25427
25564
|
about,
|
|
@@ -25433,7 +25570,8 @@ var handleQuery = async (ctx, { flags }) => {
|
|
|
25433
25570
|
cursor,
|
|
25434
25571
|
componentId,
|
|
25435
25572
|
excludeComponents,
|
|
25436
|
-
excludeInfraShapes
|
|
25573
|
+
excludeInfraShapes,
|
|
25574
|
+
where: where.length > 0 ? where : undefined
|
|
25437
25575
|
});
|
|
25438
25576
|
writeOutput(ctx, result, () => renderQueryResults(ctx.out, c, result));
|
|
25439
25577
|
};
|
|
@@ -25452,7 +25590,8 @@ async function fetchAllQueryPages(ctx, org, repo, opts) {
|
|
|
25452
25590
|
cursor,
|
|
25453
25591
|
componentId: opts.componentId,
|
|
25454
25592
|
excludeComponents: opts.excludeComponents,
|
|
25455
|
-
excludeInfraShapes: opts.excludeInfraShapes
|
|
25593
|
+
excludeInfraShapes: opts.excludeInfraShapes,
|
|
25594
|
+
where: opts.where
|
|
25456
25595
|
});
|
|
25457
25596
|
items.push(...page.items ?? []);
|
|
25458
25597
|
if (!page.nextCursor)
|
|
@@ -33437,20 +33576,36 @@ var handleUpdate3 = async (ctx, { args, flags }) => {
|
|
|
33437
33576
|
ctx.out(`${c.green}Updated${c.reset} ${c.cyan}${orgName}/${repoName}${c.reset} description`);
|
|
33438
33577
|
});
|
|
33439
33578
|
};
|
|
33440
|
-
var
|
|
33579
|
+
var describeFlags = {
|
|
33580
|
+
"indexed-fields": flag.boolean({
|
|
33581
|
+
description: "Show typed field index state (building, ready, failed) for each shape"
|
|
33582
|
+
})
|
|
33583
|
+
};
|
|
33584
|
+
var handleDescribe = async (ctx, { args, flags }) => {
|
|
33441
33585
|
const repoRef = args[0];
|
|
33442
33586
|
const { org, repo } = parseOrgRepo(repoRef, ctx.config);
|
|
33443
33587
|
const c = ctx.colors;
|
|
33444
|
-
const
|
|
33588
|
+
const showIndexedFields = flags["indexed-fields"] === true;
|
|
33589
|
+
const [repoInfo, shapesPage, stats, indexedFields] = await Promise.all([
|
|
33445
33590
|
ctx.client.repo.get(org, repo),
|
|
33446
33591
|
ctx.client.shape.list(org, repo),
|
|
33447
|
-
ctx.client.repo.getStats(org, repo)
|
|
33592
|
+
ctx.client.repo.getStats(org, repo),
|
|
33593
|
+
showIndexedFields ? ctx.client.repo.index.describe(org, repo) : null
|
|
33448
33594
|
]);
|
|
33449
33595
|
const shapes = shapesPage.items;
|
|
33450
33596
|
const byShape = Object.fromEntries([
|
|
33451
33597
|
...shapes.map((shape) => shape.name).filter((name) => typeof name === "string").map((name) => [name, 0]),
|
|
33452
33598
|
...Object.entries(stats.byShape)
|
|
33453
33599
|
]);
|
|
33600
|
+
function stripShapeThingId(bucket) {
|
|
33601
|
+
return bucket.map(({ shapeThingId: _omit, ...rest }) => rest);
|
|
33602
|
+
}
|
|
33603
|
+
const indexedFieldsPublic = indexedFields ? {
|
|
33604
|
+
building: stripShapeThingId(indexedFields.building),
|
|
33605
|
+
ready: stripShapeThingId(indexedFields.ready),
|
|
33606
|
+
failed: stripShapeThingId(indexedFields.failed),
|
|
33607
|
+
other: stripShapeThingId(indexedFields.other)
|
|
33608
|
+
} : null;
|
|
33454
33609
|
const payload = {
|
|
33455
33610
|
org,
|
|
33456
33611
|
repo,
|
|
@@ -33470,7 +33625,8 @@ var handleDescribe = async (ctx, { args }) => {
|
|
|
33470
33625
|
description: typeof data?.description === "string" ? data.description : null,
|
|
33471
33626
|
fields: Object.fromEntries(Object.entries(fields).map(([k, v]) => [k, displayFieldEntry(v)]))
|
|
33472
33627
|
};
|
|
33473
|
-
})
|
|
33628
|
+
}),
|
|
33629
|
+
...indexedFieldsPublic ? { indexedFields: indexedFieldsPublic } : {}
|
|
33474
33630
|
};
|
|
33475
33631
|
writeOutput(ctx, payload, () => {
|
|
33476
33632
|
ctx.out(`${c.bold}${org}/${repo}${c.reset}`);
|
|
@@ -33521,6 +33677,52 @@ var handleDescribe = async (ctx, { args }) => {
|
|
|
33521
33677
|
}
|
|
33522
33678
|
ctx.out("");
|
|
33523
33679
|
}
|
|
33680
|
+
if (indexedFieldsPublic) {
|
|
33681
|
+
const allEntries = [
|
|
33682
|
+
...indexedFieldsPublic.building,
|
|
33683
|
+
...indexedFieldsPublic.ready,
|
|
33684
|
+
...indexedFieldsPublic.failed,
|
|
33685
|
+
...indexedFieldsPublic.other
|
|
33686
|
+
];
|
|
33687
|
+
if (allEntries.length === 0) {
|
|
33688
|
+
ctx.out(`${c.bold}Indexed Fields${c.reset} ${c.dim}none${c.reset}`);
|
|
33689
|
+
} else {
|
|
33690
|
+
ctx.out(`${c.bold}Indexed Fields${c.reset} (${allEntries.length})`);
|
|
33691
|
+
ctx.out("");
|
|
33692
|
+
const stateColor = (state) => {
|
|
33693
|
+
switch (state) {
|
|
33694
|
+
case "ready":
|
|
33695
|
+
return c.green;
|
|
33696
|
+
case "building":
|
|
33697
|
+
return c.yellow;
|
|
33698
|
+
case "failed":
|
|
33699
|
+
return c.red;
|
|
33700
|
+
default:
|
|
33701
|
+
return c.dim;
|
|
33702
|
+
}
|
|
33703
|
+
};
|
|
33704
|
+
const maxShape = allEntries.reduce((m, e) => Math.max(m, e.shapeName.length), 0);
|
|
33705
|
+
const maxField = allEntries.reduce((m, e) => Math.max(m, e.fieldPath.length), 0);
|
|
33706
|
+
const maxState = allEntries.reduce((m, e) => Math.max(m, e.state.length), 0);
|
|
33707
|
+
for (const entry of allEntries) {
|
|
33708
|
+
const shapeLabel = entry.shapeName.padEnd(maxShape);
|
|
33709
|
+
const fieldLabel = entry.fieldPath.padEnd(maxField);
|
|
33710
|
+
const stateLabel = entry.state.padEnd(maxState);
|
|
33711
|
+
const sc = stateColor(entry.state);
|
|
33712
|
+
let line = ` ${c.cyan}${shapeLabel}${c.reset} ${c.dim}${fieldLabel}${c.reset} ${sc}${stateLabel}${c.reset}`;
|
|
33713
|
+
if (entry.state === "building" && entry.backfillTotal != null && entry.backfillTotal > 0) {
|
|
33714
|
+
const pct = Math.round(entry.backfillDone / entry.backfillTotal * 100);
|
|
33715
|
+
line += ` ${c.dim}${entry.backfillDone}/${entry.backfillTotal} (${pct}%)${c.reset}`;
|
|
33716
|
+
} else if (entry.state === "building") {
|
|
33717
|
+
line += ` ${c.dim}${entry.backfillDone} rows${c.reset}`;
|
|
33718
|
+
} else if (entry.state === "failed" && entry.failureReason) {
|
|
33719
|
+
line += ` ${c.dim}${entry.failureReason}${c.reset}`;
|
|
33720
|
+
}
|
|
33721
|
+
ctx.out(line);
|
|
33722
|
+
}
|
|
33723
|
+
ctx.out("");
|
|
33724
|
+
}
|
|
33725
|
+
}
|
|
33524
33726
|
});
|
|
33525
33727
|
};
|
|
33526
33728
|
var confirmFlags2 = {
|
|
@@ -33790,7 +33992,12 @@ var REPO_DOMAIN = defineDomain({
|
|
|
33790
33992
|
prime: true,
|
|
33791
33993
|
summary: "Describe repo schema: shapes, fields, and inline descriptions",
|
|
33792
33994
|
args: "[org/repo]",
|
|
33793
|
-
|
|
33995
|
+
flags: describeFlags,
|
|
33996
|
+
examples: [
|
|
33997
|
+
"wh repo describe",
|
|
33998
|
+
"wh repo describe acme/world",
|
|
33999
|
+
"wh repo describe acme/world --indexed-fields"
|
|
34000
|
+
],
|
|
33794
34001
|
handler: handleDescribe
|
|
33795
34002
|
},
|
|
33796
34003
|
visibility: {
|
|
@@ -35860,7 +36067,7 @@ function resolveLogLevel(flags, env) {
|
|
|
35860
36067
|
// package.json
|
|
35861
36068
|
var package_default3 = {
|
|
35862
36069
|
name: "@warmhub/cli",
|
|
35863
|
-
version: "0.
|
|
36070
|
+
version: "0.45.0",
|
|
35864
36071
|
private: false,
|
|
35865
36072
|
type: "module",
|
|
35866
36073
|
homepage: "https://docs.warmhub.ai",
|
|
@@ -36094,8 +36301,11 @@ async function resolveRegisteredInstall(args) {
|
|
|
36094
36301
|
try {
|
|
36095
36302
|
return await args.client.component.registry.resolve(ownerOrg, componentName, args.installRepo);
|
|
36096
36303
|
} catch (error) {
|
|
36097
|
-
if (error instanceof WarmHubError && error.
|
|
36098
|
-
throw new CliError(2 /* UserInput */, "USER_INPUT", `No component registered as ${args.componentRef}`, undefined, `If you meant a local path, prefix it with ./${args.componentRef}
|
|
36304
|
+
if (error instanceof WarmHubError && error.backendCode === "NOT_FOUND") {
|
|
36305
|
+
throw new CliError(2 /* UserInput */, "USER_INPUT", `No component registered as ${args.componentRef}`, undefined, `If you meant a local path, prefix it with ./${args.componentRef}`, undefined, error.backendCode);
|
|
36306
|
+
}
|
|
36307
|
+
if (error instanceof WarmHubError && error.status === 404 && error.backendCode === undefined) {
|
|
36308
|
+
throw new CliError(4 /* Backend */, "BACKEND", error.message, error, "The backend may not expose the component-registry routes. Confirm the API URL points at a deployment that supports `wh component install`, or check for a proxy/path mismatch.");
|
|
36099
36309
|
}
|
|
36100
36310
|
throw toCliError2(error);
|
|
36101
36311
|
}
|
|
@@ -36186,7 +36396,7 @@ async function handleRegisteredInstall(args) {
|
|
|
36186
36396
|
});
|
|
36187
36397
|
} catch (error) {
|
|
36188
36398
|
if (isMissingManifestPermissionError(error)) {
|
|
36189
|
-
throw new CliError(2 /* UserInput */, "USER_INPUT", error.message, undefined, "Ask an org owner/admin to grant the missing permissions on the install repo, then re-run install.");
|
|
36399
|
+
throw new CliError(2 /* UserInput */, "USER_INPUT", error.message, undefined, "Ask an org owner/admin to grant the missing permissions on the install repo, then re-run install.", undefined, error.backendCode);
|
|
36190
36400
|
}
|
|
36191
36401
|
throw error;
|
|
36192
36402
|
}
|
|
@@ -36805,4 +37015,4 @@ if (!updateCheckSuppressedByArgv && shouldRunUpdateCheck(updateEligibility)) {
|
|
|
36805
37015
|
var interceptedExitCode = await maybeHandleComponentShellBoundary(dispatchArgv);
|
|
36806
37016
|
process.exitCode = interceptedExitCode === undefined ? await runCli(dispatchArgv, { version: package_default3.version }) : interceptedExitCode;
|
|
36807
37017
|
|
|
36808
|
-
//# debugId=
|
|
37018
|
+
//# debugId=3F3232411E7711A864756E2164756E21
|