@milaboratories/pl-client 3.4.2 → 3.5.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/core/final.cjs.map +1 -1
- package/dist/core/final.js.map +1 -1
- package/dist/core/ll_client.cjs +7 -1
- package/dist/core/ll_client.cjs.map +1 -1
- package/dist/core/ll_client.d.ts.map +1 -1
- package/dist/core/ll_client.js +7 -1
- package/dist/core/ll_client.js.map +1 -1
- package/dist/core/ll_transaction.cjs +151 -26
- package/dist/core/ll_transaction.cjs.map +1 -1
- package/dist/core/ll_transaction.d.ts +1 -0
- package/dist/core/ll_transaction.d.ts.map +1 -1
- package/dist/core/ll_transaction.js +151 -26
- package/dist/core/ll_transaction.js.map +1 -1
- package/dist/core/transaction.cjs +89 -0
- package/dist/core/transaction.cjs.map +1 -1
- package/dist/core/transaction.d.ts +47 -1
- package/dist/core/transaction.d.ts.map +1 -1
- package/dist/core/transaction.js +90 -1
- package/dist/core/transaction.js.map +1 -1
- package/dist/core/tree_filter.cjs +106 -0
- package/dist/core/tree_filter.cjs.map +1 -0
- package/dist/core/tree_filter.d.ts +85 -0
- package/dist/core/tree_filter.d.ts.map +1 -0
- package/dist/core/tree_filter.js +106 -0
- package/dist/core/tree_filter.js.map +1 -0
- package/dist/core/type_conversion.cjs +1 -0
- package/dist/core/type_conversion.cjs.map +1 -1
- package/dist/core/type_conversion.js +1 -1
- package/dist/core/type_conversion.js.map +1 -1
- package/dist/index.cjs +5 -0
- package/dist/index.d.ts +4 -2
- package/dist/index.js +3 -1
- package/dist/proto-grpc/github.com/googleapis/googleapis/google/rpc/status.cjs.map +1 -1
- package/dist/proto-grpc/github.com/googleapis/googleapis/google/rpc/status.js.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.cjs +450 -4
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.cjs.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.d.ts +328 -2
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.d.ts.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.js +449 -5
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.js.map +1 -1
- package/dist/proto-grpc/google/protobuf/timestamp.cjs.map +1 -1
- package/dist/proto-grpc/google/protobuf/timestamp.d.ts +9 -8
- package/dist/proto-grpc/google/protobuf/timestamp.d.ts.map +1 -1
- package/dist/proto-grpc/google/protobuf/timestamp.js.map +1 -1
- package/dist/proto-grpc/google/rpc/code.cjs.map +1 -1
- package/dist/proto-grpc/google/rpc/code.js.map +1 -1
- package/package.json +4 -4
- package/src/core/final.ts +1 -1
- package/src/core/ll_client.ts +11 -1
- package/src/core/ll_transaction.test.ts +13 -18
- package/src/core/ll_transaction.ts +237 -60
- package/src/core/transaction.test.ts +38 -0
- package/src/core/transaction.ts +136 -1
- package/src/core/tree_filter.test.ts +217 -0
- package/src/core/tree_filter.ts +182 -0
- package/src/core/type_conversion.ts +1 -1
- package/src/index.ts +1 -0
- package/src/proto-grpc/github.com/googleapis/googleapis/google/rpc/status.ts +1 -1
- package/src/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.ts +604 -6
- package/src/proto-grpc/google/api/http.ts +1 -1
- package/src/proto-grpc/google/protobuf/descriptor.ts +242 -12
- package/src/proto-grpc/google/protobuf/timestamp.ts +9 -8
- package/src/proto-grpc/google/protobuf/wrappers.ts +38 -4
- package/src/proto-grpc/google/rpc/code.ts +1 -1
- package/src/proto-grpc/google/rpc/error_details.ts +5 -5
- package/src/proto-grpc/google/rpc/http.ts +1 -1
- package/src/proto-grpc/google/rpc/status.ts +1 -1
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import { describe, expect, test } from "vitest";
|
|
2
|
+
import { treeFilter, FilterOperatorType, FilterProperty } from "./tree_filter";
|
|
3
|
+
import type { Filter } from "./tree_filter";
|
|
4
|
+
|
|
5
|
+
describe("treeFilter builders — wire shape", () => {
|
|
6
|
+
// ── Leaf helpers ───────────────────────────────────────────────────────────
|
|
7
|
+
|
|
8
|
+
test("resourceTypeEq produces EQUAL / RESOURCE_TYPE / stringValue", () => {
|
|
9
|
+
const f = treeFilter.resourceTypeEq("Blob");
|
|
10
|
+
expect(f).toEqual<Filter>({
|
|
11
|
+
key: FilterProperty.RESOURCE_TYPE,
|
|
12
|
+
operator: FilterOperatorType.EQUAL,
|
|
13
|
+
value: { oneofKind: "stringValue", stringValue: "Blob" },
|
|
14
|
+
});
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
test("resourceTypeMatch produces MATCH / RESOURCE_TYPE / stringValue", () => {
|
|
18
|
+
const f = treeFilter.resourceTypeMatch("^Blob/");
|
|
19
|
+
expect(f).toEqual<Filter>({
|
|
20
|
+
key: FilterProperty.RESOURCE_TYPE,
|
|
21
|
+
operator: FilterOperatorType.MATCH,
|
|
22
|
+
value: { oneofKind: "stringValue", stringValue: "^Blob/" },
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
test("fieldNameEq produces EQUAL / FIELD_NAME / stringValue", () => {
|
|
27
|
+
const f = treeFilter.fieldNameEq("output");
|
|
28
|
+
expect(f).toEqual<Filter>({
|
|
29
|
+
key: FilterProperty.FIELD_NAME,
|
|
30
|
+
operator: FilterOperatorType.EQUAL,
|
|
31
|
+
value: { oneofKind: "stringValue", stringValue: "output" },
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
test("fieldNameMatch produces MATCH / FIELD_NAME / stringValue", () => {
|
|
36
|
+
const f = treeFilter.fieldNameMatch("^__service");
|
|
37
|
+
expect(f).toEqual<Filter>({
|
|
38
|
+
key: FilterProperty.FIELD_NAME,
|
|
39
|
+
operator: FilterOperatorType.MATCH,
|
|
40
|
+
value: { oneofKind: "stringValue", stringValue: "^__service" },
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
test("isFinal(true) produces EQUAL / IS_FINAL / boolValue:true", () => {
|
|
45
|
+
const f = treeFilter.isFinal(true);
|
|
46
|
+
expect(f).toEqual<Filter>({
|
|
47
|
+
key: FilterProperty.IS_FINAL,
|
|
48
|
+
operator: FilterOperatorType.EQUAL,
|
|
49
|
+
value: { oneofKind: "boolValue", boolValue: true },
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
test("isFinal(false) produces EQUAL / IS_FINAL / boolValue:false", () => {
|
|
54
|
+
const f = treeFilter.isFinal(false);
|
|
55
|
+
expect(f).toEqual<Filter>({
|
|
56
|
+
key: FilterProperty.IS_FINAL,
|
|
57
|
+
operator: FilterOperatorType.EQUAL,
|
|
58
|
+
value: { oneofKind: "boolValue", boolValue: false },
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
test("allOutputsFinal(true) produces EQUAL / ALL_OUTPUTS_FINAL / boolValue:true", () => {
|
|
63
|
+
const f = treeFilter.allOutputsFinal(true);
|
|
64
|
+
expect(f).toEqual<Filter>({
|
|
65
|
+
key: FilterProperty.ALL_OUTPUTS_FINAL,
|
|
66
|
+
operator: FilterOperatorType.EQUAL,
|
|
67
|
+
value: { oneofKind: "boolValue", boolValue: true },
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
test("resourceReadyForCalculation(true) produces EQUAL / RESOURCE_READY_FOR_CALCULATION / boolValue:true", () => {
|
|
72
|
+
const f = treeFilter.resourceReadyForCalculation(true);
|
|
73
|
+
expect(f).toEqual<Filter>({
|
|
74
|
+
key: FilterProperty.RESOURCE_READY_FOR_CALCULATION,
|
|
75
|
+
operator: FilterOperatorType.EQUAL,
|
|
76
|
+
value: { oneofKind: "boolValue", boolValue: true },
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
test("isDuplicate(false) produces EQUAL / IS_DUPLICATE / boolValue:false", () => {
|
|
81
|
+
const f = treeFilter.isDuplicate(false);
|
|
82
|
+
expect(f).toEqual<Filter>({
|
|
83
|
+
key: FilterProperty.IS_DUPLICATE,
|
|
84
|
+
operator: FilterOperatorType.EQUAL,
|
|
85
|
+
value: { oneofKind: "boolValue", boolValue: false },
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
test("hasErrors(true) produces EQUAL / HAS_ERRORS / boolValue:true", () => {
|
|
90
|
+
const f = treeFilter.hasErrors(true);
|
|
91
|
+
expect(f).toEqual<Filter>({
|
|
92
|
+
key: FilterProperty.HAS_ERRORS,
|
|
93
|
+
operator: FilterOperatorType.EQUAL,
|
|
94
|
+
value: { oneofKind: "boolValue", boolValue: true },
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
test("outputsLocked(true) produces EQUAL / OUTPUTS_LOCKED / boolValue:true", () => {
|
|
99
|
+
const f = treeFilter.outputsLocked(true);
|
|
100
|
+
expect(f).toEqual<Filter>({
|
|
101
|
+
key: FilterProperty.OUTPUTS_LOCKED,
|
|
102
|
+
operator: FilterOperatorType.EQUAL,
|
|
103
|
+
value: { oneofKind: "boolValue", boolValue: true },
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
test("readyOrDuplicateOrError() produces OR of the three conditions", () => {
|
|
108
|
+
const f = treeFilter.readyOrDuplicateOrError();
|
|
109
|
+
expect(f.operator).toBe(FilterOperatorType.OR);
|
|
110
|
+
if (f.value.oneofKind !== "filtersValue") throw new Error("expected filtersValue");
|
|
111
|
+
const { filters } = f.value.filtersValue;
|
|
112
|
+
expect(filters).toHaveLength(3);
|
|
113
|
+
expect(filters[0]).toEqual<Filter>({
|
|
114
|
+
key: FilterProperty.RESOURCE_READY_FOR_CALCULATION,
|
|
115
|
+
operator: FilterOperatorType.EQUAL,
|
|
116
|
+
value: { oneofKind: "boolValue", boolValue: true },
|
|
117
|
+
});
|
|
118
|
+
expect(filters[1]).toEqual<Filter>({
|
|
119
|
+
key: FilterProperty.IS_DUPLICATE,
|
|
120
|
+
operator: FilterOperatorType.EQUAL,
|
|
121
|
+
value: { oneofKind: "boolValue", boolValue: true },
|
|
122
|
+
});
|
|
123
|
+
expect(filters[2]).toEqual<Filter>({
|
|
124
|
+
key: FilterProperty.HAS_ERRORS,
|
|
125
|
+
operator: FilterOperatorType.EQUAL,
|
|
126
|
+
value: { oneofKind: "boolValue", boolValue: true },
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
test("generic eq() and match() use supplied property", () => {
|
|
131
|
+
expect(treeFilter.eq(FilterProperty.RESOURCE_TYPE, "Foo")).toEqual<Filter>({
|
|
132
|
+
key: FilterProperty.RESOURCE_TYPE,
|
|
133
|
+
operator: FilterOperatorType.EQUAL,
|
|
134
|
+
value: { oneofKind: "stringValue", stringValue: "Foo" },
|
|
135
|
+
});
|
|
136
|
+
expect(treeFilter.match(FilterProperty.FIELD_NAME, "^out")).toEqual<Filter>({
|
|
137
|
+
key: FilterProperty.FIELD_NAME,
|
|
138
|
+
operator: FilterOperatorType.MATCH,
|
|
139
|
+
value: { oneofKind: "stringValue", stringValue: "^out" },
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
// ── Group operators ────────────────────────────────────────────────────────
|
|
144
|
+
|
|
145
|
+
test("and() wraps children in AND / filtersValue", () => {
|
|
146
|
+
const a = treeFilter.resourceTypeEq("A");
|
|
147
|
+
const b = treeFilter.resourceTypeEq("B");
|
|
148
|
+
const f = treeFilter.and(a, b);
|
|
149
|
+
expect(f).toEqual<Filter>({
|
|
150
|
+
operator: FilterOperatorType.AND,
|
|
151
|
+
value: { oneofKind: "filtersValue", filtersValue: { filters: [a, b] } },
|
|
152
|
+
});
|
|
153
|
+
// key must be absent for group operators
|
|
154
|
+
expect(f.key).toBeUndefined();
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
test("or() wraps children in OR / filtersValue", () => {
|
|
158
|
+
const a = treeFilter.isFinal(true);
|
|
159
|
+
const b = treeFilter.allOutputsFinal(true);
|
|
160
|
+
const f = treeFilter.or(a, b);
|
|
161
|
+
expect(f).toEqual<Filter>({
|
|
162
|
+
operator: FilterOperatorType.OR,
|
|
163
|
+
value: { oneofKind: "filtersValue", filtersValue: { filters: [a, b] } },
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
test("not() wraps single child in NOT / filtersValue", () => {
|
|
168
|
+
const inner = treeFilter.resourceTypeEq("Blob");
|
|
169
|
+
const f = treeFilter.not(inner);
|
|
170
|
+
expect(f).toEqual<Filter>({
|
|
171
|
+
operator: FilterOperatorType.NOT,
|
|
172
|
+
value: { oneofKind: "filtersValue", filtersValue: { filters: [inner] } },
|
|
173
|
+
});
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
// ── Nested composition ────────────────────────────────────────────────────
|
|
177
|
+
|
|
178
|
+
test("nested AND(RESOURCE_TYPE, IS_FINAL) round-trips correctly", () => {
|
|
179
|
+
// Mirrors the Go-side mustCompileTraverseStopRules usage:
|
|
180
|
+
// AND(RESOURCE_TYPE == "StdMap", IS_FINAL == true)
|
|
181
|
+
const f = treeFilter.and(treeFilter.resourceTypeEq("StdMap"), treeFilter.isFinal(true));
|
|
182
|
+
|
|
183
|
+
expect(f.operator).toBe(FilterOperatorType.AND);
|
|
184
|
+
expect(f.key).toBeUndefined();
|
|
185
|
+
if (f.value.oneofKind !== "filtersValue") throw new Error("expected filtersValue");
|
|
186
|
+
|
|
187
|
+
const { filters } = f.value.filtersValue;
|
|
188
|
+
expect(filters).toHaveLength(2);
|
|
189
|
+
|
|
190
|
+
expect(filters[0]).toEqual<Filter>({
|
|
191
|
+
key: FilterProperty.RESOURCE_TYPE,
|
|
192
|
+
operator: FilterOperatorType.EQUAL,
|
|
193
|
+
value: { oneofKind: "stringValue", stringValue: "StdMap" },
|
|
194
|
+
});
|
|
195
|
+
expect(filters[1]).toEqual<Filter>({
|
|
196
|
+
key: FilterProperty.IS_FINAL,
|
|
197
|
+
operator: FilterOperatorType.EQUAL,
|
|
198
|
+
value: { oneofKind: "boolValue", boolValue: true },
|
|
199
|
+
});
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
test("NOT(AND(RESOURCE_TYPE, FIELD_NAME)) used in field_filters", () => {
|
|
203
|
+
// NOT( AND(RESOURCE_TYPE == "BlockPackCustom", FIELD_NAME == "template") )
|
|
204
|
+
const f = treeFilter.not(
|
|
205
|
+
treeFilter.and(
|
|
206
|
+
treeFilter.resourceTypeEq("BlockPackCustom"),
|
|
207
|
+
treeFilter.fieldNameEq("template"),
|
|
208
|
+
),
|
|
209
|
+
);
|
|
210
|
+
expect(f.operator).toBe(FilterOperatorType.NOT);
|
|
211
|
+
if (f.value.oneofKind !== "filtersValue") throw new Error("expected filtersValue");
|
|
212
|
+
const [andNode] = f.value.filtersValue.filters;
|
|
213
|
+
expect(andNode.operator).toBe(FilterOperatorType.AND);
|
|
214
|
+
if (andNode.value.oneofKind !== "filtersValue") throw new Error("expected filtersValue");
|
|
215
|
+
expect(andNode.value.filtersValue.filters).toHaveLength(2);
|
|
216
|
+
});
|
|
217
|
+
});
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import type { ResourceAPI_Tree_Filter } from "../proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api";
|
|
2
|
+
import {
|
|
3
|
+
ResourceAPI_Tree_Filter_OperatorType,
|
|
4
|
+
ResourceAPI_Tree_Filter_Property,
|
|
5
|
+
} from "../proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api";
|
|
6
|
+
|
|
7
|
+
export type { ResourceAPI_Tree_Filter };
|
|
8
|
+
|
|
9
|
+
/** Shorthand alias for the filter predicate type. */
|
|
10
|
+
export type Filter = ResourceAPI_Tree_Filter;
|
|
11
|
+
|
|
12
|
+
/** Shorthand alias for the Property enum. */
|
|
13
|
+
export type Property = ResourceAPI_Tree_Filter_Property;
|
|
14
|
+
|
|
15
|
+
// Re-export enum namespaces under shorter aliases so callers need not import api.ts directly.
|
|
16
|
+
export { ResourceAPI_Tree_Filter_OperatorType as FilterOperatorType };
|
|
17
|
+
export { ResourceAPI_Tree_Filter_Property as FilterProperty };
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Builder helpers for {@link ResourceAPI_Tree_Filter} predicates used in
|
|
21
|
+
* `ResourceAPI_Tree_Request.fieldFilter` and `traverseStopRules`.
|
|
22
|
+
*
|
|
23
|
+
* Property restrictions (not enforced here; the backend rejects invalid combinations):
|
|
24
|
+
* - `FIELD_NAME` is only valid inside `fieldFilter`.
|
|
25
|
+
* - `IS_FINAL`, `ALL_OUTPUTS_FINAL`, and resource-level boolean predicates are only valid inside `traverseStopRules`.
|
|
26
|
+
*/
|
|
27
|
+
export const treeFilter = {
|
|
28
|
+
// ── Group operators ──────────────────────────────────────────────────────
|
|
29
|
+
|
|
30
|
+
and(...children: Filter[]): Filter {
|
|
31
|
+
return {
|
|
32
|
+
operator: ResourceAPI_Tree_Filter_OperatorType.AND,
|
|
33
|
+
value: { oneofKind: "filtersValue", filtersValue: { filters: children } },
|
|
34
|
+
};
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
or(...children: Filter[]): Filter {
|
|
38
|
+
return {
|
|
39
|
+
operator: ResourceAPI_Tree_Filter_OperatorType.OR,
|
|
40
|
+
value: { oneofKind: "filtersValue", filtersValue: { filters: children } },
|
|
41
|
+
};
|
|
42
|
+
},
|
|
43
|
+
|
|
44
|
+
not(child: Filter): Filter {
|
|
45
|
+
return {
|
|
46
|
+
operator: ResourceAPI_Tree_Filter_OperatorType.NOT,
|
|
47
|
+
value: { oneofKind: "filtersValue", filtersValue: { filters: [child] } },
|
|
48
|
+
};
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
// ── Generic leaf operators ───────────────────────────────────────────────
|
|
52
|
+
|
|
53
|
+
/** Exact-match predicate on a string property. */
|
|
54
|
+
eq(prop: Property, value: string): Filter {
|
|
55
|
+
return {
|
|
56
|
+
key: prop,
|
|
57
|
+
operator: ResourceAPI_Tree_Filter_OperatorType.EQUAL,
|
|
58
|
+
value: { oneofKind: "stringValue", stringValue: value },
|
|
59
|
+
};
|
|
60
|
+
},
|
|
61
|
+
|
|
62
|
+
/** Regex-match predicate on a string property. */
|
|
63
|
+
match(prop: Property, pattern: string): Filter {
|
|
64
|
+
return {
|
|
65
|
+
key: prop,
|
|
66
|
+
operator: ResourceAPI_Tree_Filter_OperatorType.MATCH,
|
|
67
|
+
value: { oneofKind: "stringValue", stringValue: pattern },
|
|
68
|
+
};
|
|
69
|
+
},
|
|
70
|
+
|
|
71
|
+
/** Boolean-equality predicate. */
|
|
72
|
+
boolEq(prop: Property, value: boolean): Filter {
|
|
73
|
+
return {
|
|
74
|
+
key: prop,
|
|
75
|
+
operator: ResourceAPI_Tree_Filter_OperatorType.EQUAL,
|
|
76
|
+
value: { oneofKind: "boolValue", boolValue: value },
|
|
77
|
+
};
|
|
78
|
+
},
|
|
79
|
+
|
|
80
|
+
// ── Typed convenience wrappers ───────────────────────────────────────────
|
|
81
|
+
|
|
82
|
+
/** Match resources whose type string equals `name` exactly. */
|
|
83
|
+
resourceTypeEq(name: string): Filter {
|
|
84
|
+
return treeFilter.eq(ResourceAPI_Tree_Filter_Property.RESOURCE_TYPE, name);
|
|
85
|
+
},
|
|
86
|
+
|
|
87
|
+
/** Match resources whose type string satisfies the regex `pattern`. */
|
|
88
|
+
resourceTypeMatch(pattern: string): Filter {
|
|
89
|
+
return treeFilter.match(ResourceAPI_Tree_Filter_Property.RESOURCE_TYPE, pattern);
|
|
90
|
+
},
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Match field edges whose name equals `name` exactly.
|
|
94
|
+
* Valid only inside `fieldFilter`.
|
|
95
|
+
*/
|
|
96
|
+
fieldNameEq(name: string): Filter {
|
|
97
|
+
return treeFilter.eq(ResourceAPI_Tree_Filter_Property.FIELD_NAME, name);
|
|
98
|
+
},
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Match field edges whose name satisfies the regex `pattern`.
|
|
102
|
+
* Valid only inside `fieldFilter`.
|
|
103
|
+
*/
|
|
104
|
+
fieldNameMatch(pattern: string): Filter {
|
|
105
|
+
return treeFilter.match(ResourceAPI_Tree_Filter_Property.FIELD_NAME, pattern);
|
|
106
|
+
},
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Match resources where `is_final == value`.
|
|
110
|
+
* Valid only inside `traverseStopRules`.
|
|
111
|
+
*/
|
|
112
|
+
isFinal(value: boolean): Filter {
|
|
113
|
+
return treeFilter.boolEq(ResourceAPI_Tree_Filter_Property.IS_FINAL, value);
|
|
114
|
+
},
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Match resources where `all_outputs_final == value`.
|
|
118
|
+
* Valid only inside `traverseStopRules`.
|
|
119
|
+
*/
|
|
120
|
+
allOutputsFinal(value: boolean): Filter {
|
|
121
|
+
return treeFilter.boolEq(ResourceAPI_Tree_Filter_Property.ALL_OUTPUTS_FINAL, value);
|
|
122
|
+
},
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Match resources where `resource_ready_for_calculation == value`.
|
|
126
|
+
* True when the resource is Original, inputs are locked, and all inputs are final.
|
|
127
|
+
* Valid only inside `traverseStopRules`.
|
|
128
|
+
*/
|
|
129
|
+
resourceReadyForCalculation(value: boolean): Filter {
|
|
130
|
+
return treeFilter.boolEq(
|
|
131
|
+
ResourceAPI_Tree_Filter_Property.RESOURCE_READY_FOR_CALCULATION,
|
|
132
|
+
value,
|
|
133
|
+
);
|
|
134
|
+
},
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Match resources where `is_duplicate == value`.
|
|
138
|
+
* True when the resource has a non-zero original_resource_id.
|
|
139
|
+
* Valid only inside `traverseStopRules`.
|
|
140
|
+
*/
|
|
141
|
+
isDuplicate(value: boolean): Filter {
|
|
142
|
+
return treeFilter.boolEq(ResourceAPI_Tree_Filter_Property.IS_DUPLICATE, value);
|
|
143
|
+
},
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Match resources where `has_errors == value`.
|
|
147
|
+
* True when the resource has at least one field carrying an error (aggregated
|
|
148
|
+
* has-error flag). Can be true even when the resource's own status is not
|
|
149
|
+
* Error (e.g., an Original resource with a failed input field).
|
|
150
|
+
* Valid only inside `traverseStopRules`.
|
|
151
|
+
*/
|
|
152
|
+
hasErrors(value: boolean): Filter {
|
|
153
|
+
return treeFilter.boolEq(ResourceAPI_Tree_Filter_Property.HAS_ERRORS, value);
|
|
154
|
+
},
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Match resources where `outputs_locked == value`.
|
|
158
|
+
* Valid only inside `traverseStopRules`.
|
|
159
|
+
*/
|
|
160
|
+
outputsLocked(value: boolean): Filter {
|
|
161
|
+
return treeFilter.boolEq(ResourceAPI_Tree_Filter_Property.OUTPUTS_LOCKED, value);
|
|
162
|
+
},
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Match resources that are ready-or-duplicate-or-error: mirrors the BFS
|
|
166
|
+
* `readyOrDuplicateOrError` predicate used by pl-tree to decide whether a
|
|
167
|
+
* resource subtree needs further polling.
|
|
168
|
+
*
|
|
169
|
+
* Use this as `traverseStopRules` to stop the server-side tree walk at
|
|
170
|
+
* exactly the same nodes where the client BFS would stop, eliminating
|
|
171
|
+
* unnecessary follow-up calls.
|
|
172
|
+
*
|
|
173
|
+
* Valid only inside `traverseStopRules`.
|
|
174
|
+
*/
|
|
175
|
+
readyOrDuplicateOrError(): Filter {
|
|
176
|
+
return treeFilter.or(
|
|
177
|
+
treeFilter.resourceReadyForCalculation(true),
|
|
178
|
+
treeFilter.isDuplicate(true),
|
|
179
|
+
treeFilter.hasErrors(true),
|
|
180
|
+
);
|
|
181
|
+
},
|
|
182
|
+
} as const;
|
|
@@ -26,7 +26,7 @@ import { throwPlNotFoundError } from "./errors";
|
|
|
26
26
|
|
|
27
27
|
const ResourceErrorField = "resourceError";
|
|
28
28
|
|
|
29
|
-
function resourceIsDeleted(proto: Resource): boolean {
|
|
29
|
+
export function resourceIsDeleted(proto: Resource): boolean {
|
|
30
30
|
return proto.deletedTime !== undefined && proto.deletedTime.seconds !== 0n;
|
|
31
31
|
}
|
|
32
32
|
|
package/src/index.ts
CHANGED
|
@@ -9,6 +9,7 @@ export * from "./core/default_client";
|
|
|
9
9
|
export * from "./core/unauth_client";
|
|
10
10
|
export * from "./core/auth";
|
|
11
11
|
export * from "./core/final";
|
|
12
|
+
export * from "./core/tree_filter";
|
|
12
13
|
export * from "./core/user_resources";
|
|
13
14
|
export * from "./core/wire";
|
|
14
15
|
export * from "./helpers/tx_helpers";
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// @generated from protobuf file "github.com/googleapis/googleapis/google/rpc/status.proto" (package "google.rpc", syntax proto3)
|
|
3
3
|
// tslint:disable
|
|
4
4
|
//
|
|
5
|
-
// Copyright
|
|
5
|
+
// Copyright 2026 Google LLC
|
|
6
6
|
//
|
|
7
7
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
8
|
// you may not use this file except in compliance with the License.
|