@milaboratories/pl-client 3.2.5 → 3.3.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/client.cjs +24 -56
- package/dist/core/client.cjs.map +1 -1
- package/dist/core/client.d.ts +12 -8
- package/dist/core/client.d.ts.map +1 -1
- package/dist/core/client.js +26 -58
- package/dist/core/client.js.map +1 -1
- package/dist/core/errors.cjs +20 -0
- package/dist/core/errors.cjs.map +1 -1
- package/dist/core/errors.d.ts +6 -1
- package/dist/core/errors.d.ts.map +1 -1
- package/dist/core/errors.js +19 -1
- package/dist/core/errors.js.map +1 -1
- package/dist/core/final.cjs +6 -5
- package/dist/core/final.cjs.map +1 -1
- package/dist/core/final.d.ts.map +1 -1
- package/dist/core/final.js +7 -6
- package/dist/core/final.js.map +1 -1
- package/dist/core/ll_client.cjs +18 -1
- package/dist/core/ll_client.cjs.map +1 -1
- package/dist/core/ll_client.d.ts +6 -2
- package/dist/core/ll_client.d.ts.map +1 -1
- package/dist/core/ll_client.js +19 -2
- package/dist/core/ll_client.js.map +1 -1
- package/dist/core/transaction.cjs +109 -75
- package/dist/core/transaction.cjs.map +1 -1
- package/dist/core/transaction.d.ts +30 -22
- package/dist/core/transaction.d.ts.map +1 -1
- package/dist/core/transaction.js +111 -76
- package/dist/core/transaction.js.map +1 -1
- package/dist/core/type_conversion.cjs +14 -6
- package/dist/core/type_conversion.cjs.map +1 -1
- package/dist/core/type_conversion.js +14 -6
- package/dist/core/type_conversion.js.map +1 -1
- package/dist/core/types.cjs +77 -17
- package/dist/core/types.cjs.map +1 -1
- package/dist/core/types.d.ts +49 -26
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js +66 -14
- package/dist/core/types.js.map +1 -1
- package/dist/core/user_resources.cjs +181 -0
- package/dist/core/user_resources.cjs.map +1 -0
- package/dist/core/user_resources.d.ts +75 -0
- package/dist/core/user_resources.d.ts.map +1 -0
- package/dist/core/user_resources.js +180 -0
- package/dist/core/user_resources.js.map +1 -0
- package/dist/helpers/poll.cjs +4 -4
- package/dist/helpers/poll.cjs.map +1 -1
- package/dist/helpers/poll.d.ts +3 -3
- package/dist/helpers/poll.d.ts.map +1 -1
- package/dist/helpers/poll.js +5 -5
- package/dist/helpers/poll.js.map +1 -1
- package/dist/helpers/tx_helpers.cjs +1 -1
- package/dist/helpers/tx_helpers.cjs.map +1 -1
- package/dist/helpers/tx_helpers.d.ts +3 -3
- package/dist/helpers/tx_helpers.d.ts.map +1 -1
- package/dist/helpers/tx_helpers.js +2 -2
- package/dist/helpers/tx_helpers.js.map +1 -1
- package/dist/index.cjs +16 -5
- package/dist/index.d.ts +5 -4
- package/dist/index.js +5 -4
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.cjs +724 -188
- 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.client.cjs +34 -9
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.client.cjs.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.client.d.ts +37 -5
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.client.d.ts.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.client.js +34 -9
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.client.js.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.d.ts +326 -136
- 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 +724 -188
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.js.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api_types.cjs +18 -7
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api_types.cjs.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api_types.d.ts +11 -7
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api_types.d.ts.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api_types.js +18 -7
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api_types.js.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/base_types.cjs +57 -2
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/base_types.cjs.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/base_types.d.ts +26 -3
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/base_types.d.ts.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/base_types.js +57 -3
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/base_types.js.map +1 -1
- package/dist/proto-rest/plapi.d.ts +421 -207
- package/dist/proto-rest/plapi.d.ts.map +1 -1
- package/dist/test/test_config.cjs +6 -3
- package/dist/test/test_config.cjs.map +1 -1
- package/dist/test/test_config.d.ts.map +1 -1
- package/dist/test/test_config.js +7 -4
- package/dist/test/test_config.js.map +1 -1
- package/package.json +5 -5
- package/src/core/client.ts +58 -103
- package/src/core/errors.ts +23 -0
- package/src/core/final.ts +16 -6
- package/src/core/ll_client.ts +39 -3
- package/src/core/ll_transaction.test.ts +41 -6
- package/src/core/transaction.ts +176 -86
- package/src/core/type_conversion.ts +24 -9
- package/src/core/types.ts +147 -41
- package/src/core/user_resources.ts +332 -0
- package/src/helpers/poll.ts +15 -8
- package/src/helpers/state_helpers.ts +2 -2
- package/src/helpers/tx_helpers.ts +5 -5
- package/src/index.ts +1 -0
- package/src/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.client.ts +61 -14
- package/src/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.ts +1045 -379
- package/src/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api_types.ts +33 -18
- package/src/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/base_types.ts +75 -6
- package/src/proto-grpc/google/protobuf/descriptor.ts +5 -2
- package/src/proto-rest/plapi.ts +447 -225
- package/src/test/test_config.ts +8 -5
package/src/core/final.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Optional } from "utility-types";
|
|
2
2
|
import type { BasicResourceData, ResourceData } from "./types";
|
|
3
|
-
import { getField,
|
|
3
|
+
import { getField, isNotNullSignedResourceId, isNullSignedResourceId } from "./types";
|
|
4
4
|
import { ResourceTypeName, ResourceTypePrefix } from "@milaboratories/pl-model-common";
|
|
5
5
|
export { ResourceTypeName, ResourceTypePrefix };
|
|
6
6
|
|
|
@@ -19,7 +19,9 @@ export type FinalResourceDataPredicate = (
|
|
|
19
19
|
|
|
20
20
|
function readyOrDuplicateOrError(r: ResourceData | BasicResourceData): boolean {
|
|
21
21
|
return (
|
|
22
|
-
r.resourceReady ||
|
|
22
|
+
r.resourceReady ||
|
|
23
|
+
isNotNullSignedResourceId(r.originalResourceId) ||
|
|
24
|
+
isNotNullSignedResourceId(r.error)
|
|
23
25
|
);
|
|
24
26
|
}
|
|
25
27
|
|
|
@@ -28,7 +30,8 @@ function readyAndHasAllOutputsFilled(r: Optional<ResourceData, "fields">): boole
|
|
|
28
30
|
if (!r.outputsLocked) return false;
|
|
29
31
|
if (r.fields === undefined) return true; // if fields are not provided basic resource state is not expected to change in the future
|
|
30
32
|
for (const f of r.fields)
|
|
31
|
-
if (
|
|
33
|
+
if (isNullSignedResourceId(f.error) && (isNullSignedResourceId(f.value) || !f.valueIsFinal))
|
|
34
|
+
return false;
|
|
32
35
|
return true;
|
|
33
36
|
}
|
|
34
37
|
|
|
@@ -41,7 +44,7 @@ export const DefaultFinalResourceDataPredicate: FinalResourceDataPredicate = (r)
|
|
|
41
44
|
case ResourceTypeName.StreamManager: {
|
|
42
45
|
if (!readyOrDuplicateOrError(r)) return false;
|
|
43
46
|
if (r.fields === undefined) return true; // if fields are not provided basic resource state is not expected to change in the future
|
|
44
|
-
if (
|
|
47
|
+
if (isNotNullSignedResourceId(r.error)) return true;
|
|
45
48
|
const downloadable = getField(r as ResourceData, "downloadable");
|
|
46
49
|
const stream = getField(r as ResourceData, "stream");
|
|
47
50
|
return stream.value === downloadable.value;
|
|
@@ -79,14 +82,21 @@ export const DefaultFinalResourceDataPredicate: FinalResourceDataPredicate = (r)
|
|
|
79
82
|
case ResourceTypeName.Null:
|
|
80
83
|
case ResourceTypeName.Binary:
|
|
81
84
|
case ResourceTypeName.LSProvider:
|
|
85
|
+
case ResourceTypeName.WorkingDirectory:
|
|
82
86
|
return true;
|
|
83
87
|
case ResourceTypeName.UserProject:
|
|
84
88
|
case ResourceTypeName.Projects:
|
|
85
89
|
case ResourceTypeName.ClientRoot:
|
|
86
90
|
return false;
|
|
87
91
|
default:
|
|
88
|
-
if (
|
|
89
|
-
|
|
92
|
+
if (
|
|
93
|
+
r.type.name.startsWith(ResourceTypePrefix.Blob) ||
|
|
94
|
+
r.type.name.startsWith(ResourceTypePrefix.LS) ||
|
|
95
|
+
r.type.name.startsWith(ResourceTypePrefix.WorkingDirectory) ||
|
|
96
|
+
r.type.name.startsWith(ResourceTypePrefix.StorageSpaceAllocation)
|
|
97
|
+
) {
|
|
98
|
+
return true;
|
|
99
|
+
} else if (
|
|
90
100
|
r.type.name.startsWith(ResourceTypePrefix.BlobUpload) ||
|
|
91
101
|
r.type.name.startsWith(ResourceTypePrefix.BlobIndex)
|
|
92
102
|
) {
|
package/src/core/ll_client.ts
CHANGED
|
@@ -35,7 +35,7 @@ import { notEmpty, retry, withTimeout, type RetryOptions } from "@milaboratories
|
|
|
35
35
|
import { Code } from "../proto-grpc/google/rpc/code";
|
|
36
36
|
import { WebSocketBiDiStream } from "./websocket_stream";
|
|
37
37
|
import {
|
|
38
|
-
|
|
38
|
+
AuthAPI_Role,
|
|
39
39
|
TxAPI_ClientMessage,
|
|
40
40
|
TxAPI_ServerMessage,
|
|
41
41
|
} from "../proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api";
|
|
@@ -463,10 +463,10 @@ export class LLPlClient implements WireClientProviderFactory {
|
|
|
463
463
|
|
|
464
464
|
public async getJwtToken(
|
|
465
465
|
ttlSeconds: bigint,
|
|
466
|
-
options?: { authorization?: string; role?:
|
|
466
|
+
options?: { authorization?: string; role?: AuthAPI_Role },
|
|
467
467
|
): Promise<string> {
|
|
468
468
|
const cl = this.clientProvider.get();
|
|
469
|
-
const role = options?.role ??
|
|
469
|
+
const role = options?.role ?? AuthAPI_Role.UNSPECIFIED;
|
|
470
470
|
|
|
471
471
|
if (cl instanceof GrpcPlApiClient) {
|
|
472
472
|
const meta: Record<string, string> = {};
|
|
@@ -592,6 +592,42 @@ export class LLPlClient implements WireClientProviderFactory {
|
|
|
592
592
|
}
|
|
593
593
|
}
|
|
594
594
|
|
|
595
|
+
public async getUserRoot(
|
|
596
|
+
opts: { login?: string; doNotCreate?: boolean } = {},
|
|
597
|
+
): Promise<grpcTypes.AuthAPI_GetUserRoot_Response> {
|
|
598
|
+
const cl = this.clientProvider.get();
|
|
599
|
+
if (cl instanceof GrpcPlApiClient) {
|
|
600
|
+
return (
|
|
601
|
+
await cl.getUserRoot({
|
|
602
|
+
login: opts.login ?? "",
|
|
603
|
+
doNotCreate: opts.doNotCreate ?? false,
|
|
604
|
+
})
|
|
605
|
+
).response;
|
|
606
|
+
} else {
|
|
607
|
+
const resp = notEmpty(
|
|
608
|
+
(
|
|
609
|
+
await cl.POST("/v1/auth/user-root", {
|
|
610
|
+
body: {
|
|
611
|
+
login: opts.login ?? "",
|
|
612
|
+
doNotCreate: opts.doNotCreate ?? false,
|
|
613
|
+
},
|
|
614
|
+
})
|
|
615
|
+
).data,
|
|
616
|
+
"REST: empty response for getUserRoot request",
|
|
617
|
+
);
|
|
618
|
+
return {
|
|
619
|
+
userRoot: resp.userRoot
|
|
620
|
+
? {
|
|
621
|
+
resourceId: BigInt(resp.userRoot.resourceId),
|
|
622
|
+
resourceSignature: Uint8Array.from(
|
|
623
|
+
Buffer.from(resp.userRoot.resourceSignature, "base64"),
|
|
624
|
+
),
|
|
625
|
+
}
|
|
626
|
+
: undefined,
|
|
627
|
+
};
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
|
|
595
631
|
public async listUserResources(
|
|
596
632
|
opts: { login?: string; startFrom?: bigint; limit?: number } = {},
|
|
597
633
|
): Promise<grpcTypes.AuthAPI_ListUserResources_Response[]> {
|
|
@@ -6,6 +6,23 @@ import { test, expect } from "vitest";
|
|
|
6
6
|
import { isTimeoutOrCancelError } from "./errors";
|
|
7
7
|
import { Aborted } from "@milaboratories/ts-helpers";
|
|
8
8
|
|
|
9
|
+
/** Cached root signature — fetched once, shared across tests. */
|
|
10
|
+
let cachedRootSig: Uint8Array | undefined;
|
|
11
|
+
|
|
12
|
+
async function getRootSignature(): Promise<Uint8Array> {
|
|
13
|
+
if (cachedRootSig !== undefined) return cachedRootSig;
|
|
14
|
+
const client = await getTestLLClient();
|
|
15
|
+
const responses = await client.listUserResources({ limit: 1 });
|
|
16
|
+
for (const msg of responses) {
|
|
17
|
+
if (msg.entry.oneofKind === "userRoot" && msg.entry.userRoot.resourceSignature) {
|
|
18
|
+
cachedRootSig = msg.entry.userRoot.resourceSignature;
|
|
19
|
+
return cachedRootSig;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
cachedRootSig = new Uint8Array(0);
|
|
23
|
+
return cachedRootSig;
|
|
24
|
+
}
|
|
25
|
+
|
|
9
26
|
test("check successful transaction", async () => {
|
|
10
27
|
const client = await getTestLLClient();
|
|
11
28
|
const tx = client.createTx(true);
|
|
@@ -80,6 +97,7 @@ test("check timeout error type (passive)", async () => {
|
|
|
80
97
|
|
|
81
98
|
test("check timeout error type (active)", async () => {
|
|
82
99
|
const client = await getTestLLClient();
|
|
100
|
+
const rootSig = await getRootSignature();
|
|
83
101
|
const tx = client.createTx(true, { timeout: 500 });
|
|
84
102
|
|
|
85
103
|
try {
|
|
@@ -96,6 +114,12 @@ test("check timeout error type (active)", async () => {
|
|
|
96
114
|
);
|
|
97
115
|
expect(openResponse.txOpen.tx?.isValid).toBeTruthy();
|
|
98
116
|
|
|
117
|
+
// Set default color so resource creation succeeds in strict mode
|
|
118
|
+
await tx.send(
|
|
119
|
+
{ oneofKind: "setDefaultColor", setDefaultColor: { colorProof: rootSig } },
|
|
120
|
+
false,
|
|
121
|
+
);
|
|
122
|
+
|
|
99
123
|
const rData = Uint8Array.from([
|
|
100
124
|
(Math.random() * 256) & 0xff,
|
|
101
125
|
(Math.random() * 256) & 0xff,
|
|
@@ -112,15 +136,17 @@ test("check timeout error type (active)", async () => {
|
|
|
112
136
|
oneofKind: "resourceCreateValue",
|
|
113
137
|
resourceCreateValue: {
|
|
114
138
|
id: createLocalResourceId(false, 1, 1),
|
|
139
|
+
colorProof: new Uint8Array(0),
|
|
115
140
|
type: { name: "TestValue", version: "1" },
|
|
116
141
|
data: rData,
|
|
117
142
|
errorIfExists: false,
|
|
118
|
-
colorProof: new Uint8Array(0),
|
|
119
143
|
},
|
|
120
144
|
},
|
|
121
145
|
false,
|
|
122
146
|
);
|
|
123
|
-
const
|
|
147
|
+
const createResp = (await createResponse).resourceCreateValue;
|
|
148
|
+
const id = createResp.resourceId;
|
|
149
|
+
const resourceSignature = createResp.resourceSignature ?? new Uint8Array(0);
|
|
124
150
|
|
|
125
151
|
while (true) {
|
|
126
152
|
const vr = await tx.send(
|
|
@@ -129,7 +155,7 @@ test("check timeout error type (active)", async () => {
|
|
|
129
155
|
resourceGet: {
|
|
130
156
|
resourceId: id,
|
|
131
157
|
loadFields: false,
|
|
132
|
-
resourceSignature
|
|
158
|
+
resourceSignature,
|
|
133
159
|
},
|
|
134
160
|
},
|
|
135
161
|
false,
|
|
@@ -144,6 +170,7 @@ test("check timeout error type (active)", async () => {
|
|
|
144
170
|
|
|
145
171
|
test("check is abort error (active)", async () => {
|
|
146
172
|
const client = await getTestLLClient();
|
|
173
|
+
const rootSig = await getRootSignature();
|
|
147
174
|
const tx = client.createTx(true, { abortSignal: AbortSignal.timeout(100) });
|
|
148
175
|
|
|
149
176
|
try {
|
|
@@ -160,6 +187,12 @@ test("check is abort error (active)", async () => {
|
|
|
160
187
|
);
|
|
161
188
|
expect(openResponse.txOpen.tx?.isValid).toBeTruthy();
|
|
162
189
|
|
|
190
|
+
// Set default color so resource creation succeeds in strict mode
|
|
191
|
+
await tx.send(
|
|
192
|
+
{ oneofKind: "setDefaultColor", setDefaultColor: { colorProof: rootSig } },
|
|
193
|
+
false,
|
|
194
|
+
);
|
|
195
|
+
|
|
163
196
|
const rData = Uint8Array.from([
|
|
164
197
|
Math.random() & 0xff,
|
|
165
198
|
Math.random() & 0xff,
|
|
@@ -178,13 +211,15 @@ test("check is abort error (active)", async () => {
|
|
|
178
211
|
id: createLocalResourceId(false, 1, 1),
|
|
179
212
|
type: { name: "TestValue", version: "1" },
|
|
180
213
|
data: rData,
|
|
181
|
-
errorIfExists: false,
|
|
182
214
|
colorProof: new Uint8Array(0),
|
|
215
|
+
errorIfExists: false,
|
|
183
216
|
},
|
|
184
217
|
},
|
|
185
218
|
false,
|
|
186
219
|
);
|
|
187
|
-
const
|
|
220
|
+
const createResp = (await createResponse).resourceCreateValue;
|
|
221
|
+
const id = createResp.resourceId;
|
|
222
|
+
const resourceSignature = createResp.resourceSignature ?? new Uint8Array(0);
|
|
188
223
|
|
|
189
224
|
while (true) {
|
|
190
225
|
const vr = await tx.send(
|
|
@@ -193,7 +228,7 @@ test("check is abort error (active)", async () => {
|
|
|
193
228
|
resourceGet: {
|
|
194
229
|
resourceId: id,
|
|
195
230
|
loadFields: false,
|
|
196
|
-
resourceSignature
|
|
231
|
+
resourceSignature,
|
|
197
232
|
},
|
|
198
233
|
},
|
|
199
234
|
false,
|