@milaboratories/pl-client 2.4.10
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 +52 -0
- package/dist/index.cjs +14527 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.js +14426 -0
- package/dist/index.js.map +1 -0
- package/package.json +49 -0
- package/src/core/auth.ts +27 -0
- package/src/core/client.test.ts +47 -0
- package/src/core/client.ts +302 -0
- package/src/core/config.test.ts +19 -0
- package/src/core/config.ts +197 -0
- package/src/core/default_client.ts +161 -0
- package/src/core/driver.ts +30 -0
- package/src/core/error.test.ts +14 -0
- package/src/core/errors.ts +84 -0
- package/src/core/http.ts +178 -0
- package/src/core/ll_client.test.ts +111 -0
- package/src/core/ll_client.ts +228 -0
- package/src/core/ll_transaction.test.ts +152 -0
- package/src/core/ll_transaction.ts +333 -0
- package/src/core/transaction.test.ts +173 -0
- package/src/core/transaction.ts +730 -0
- package/src/core/type_conversion.ts +121 -0
- package/src/core/types.test.ts +22 -0
- package/src/core/types.ts +223 -0
- package/src/core/unauth_client.test.ts +21 -0
- package/src/core/unauth_client.ts +48 -0
- package/src/helpers/pl.ts +141 -0
- package/src/helpers/poll.ts +178 -0
- package/src/helpers/rich_resource_types.test.ts +22 -0
- package/src/helpers/rich_resource_types.ts +84 -0
- package/src/helpers/smart_accessors.ts +146 -0
- package/src/helpers/state_helpers.ts +5 -0
- package/src/helpers/tx_helpers.ts +24 -0
- package/src/index.ts +14 -0
- package/src/proto/github.com/googleapis/googleapis/google/rpc/status.ts +125 -0
- package/src/proto/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.client.ts +45 -0
- package/src/proto/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.ts +271 -0
- package/src/proto/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.client.ts +51 -0
- package/src/proto/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.ts +380 -0
- package/src/proto/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.client.ts +59 -0
- package/src/proto/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.ts +450 -0
- package/src/proto/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.client.ts +148 -0
- package/src/proto/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.ts +706 -0
- package/src/proto/github.com/milaboratory/pl/plapi/plapiproto/api.client.ts +406 -0
- package/src/proto/github.com/milaboratory/pl/plapi/plapiproto/api.ts +12636 -0
- package/src/proto/github.com/milaboratory/pl/plapi/plapiproto/api_types.ts +1384 -0
- package/src/proto/github.com/milaboratory/pl/plapi/plapiproto/base_types.ts +181 -0
- package/src/proto/github.com/milaboratory/pl/plapi/plapiproto/import.ts +251 -0
- package/src/proto/github.com/milaboratory/pl/plapi/plapiproto/resource_types.ts +693 -0
- package/src/proto/google/api/http.ts +687 -0
- package/src/proto/google/protobuf/any.ts +326 -0
- package/src/proto/google/protobuf/descriptor.ts +4502 -0
- package/src/proto/google/protobuf/duration.ts +230 -0
- package/src/proto/google/protobuf/empty.ts +81 -0
- package/src/proto/google/protobuf/struct.ts +482 -0
- package/src/proto/google/protobuf/timestamp.ts +287 -0
- package/src/proto/google/protobuf/wrappers.ts +751 -0
- package/src/test/test_config.test.ts +6 -0
- package/src/test/test_config.ts +166 -0
- package/src/util/branding.ts +4 -0
- package/src/util/pl.ts +11 -0
- package/src/util/util.test.ts +10 -0
- package/src/util/util.ts +9 -0
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { PlClient } from '../core/client';
|
|
2
|
+
import {
|
|
3
|
+
createRetryState,
|
|
4
|
+
nextRetryStateOrError,
|
|
5
|
+
notEmpty,
|
|
6
|
+
RetryOptions
|
|
7
|
+
} from '@milaboratories/ts-helpers';
|
|
8
|
+
import {
|
|
9
|
+
FieldData,
|
|
10
|
+
FieldType,
|
|
11
|
+
isNotNullResourceId,
|
|
12
|
+
isNullResourceId,
|
|
13
|
+
ResourceData,
|
|
14
|
+
ResourceId,
|
|
15
|
+
resourceIdToString
|
|
16
|
+
} from '../core/types';
|
|
17
|
+
import { PlTransaction } from '../core/transaction';
|
|
18
|
+
import * as tp from 'node:timers/promises';
|
|
19
|
+
|
|
20
|
+
/** This error tells state assertion mechanism that required state is not yet ready */
|
|
21
|
+
export class ContinuePolling extends Error {}
|
|
22
|
+
|
|
23
|
+
export type PollFieldTraverseOps = {
|
|
24
|
+
expectedType?: FieldType;
|
|
25
|
+
/** Fail if error present along with the value, if value not present,
|
|
26
|
+
* but error do, exception will be thrown anyway. */
|
|
27
|
+
failOnError: boolean;
|
|
28
|
+
/** Traverse only if field report its value as final. */
|
|
29
|
+
onlyFinal: boolean;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const DefaultPollFieldTraverseOps: PollFieldTraverseOps = {
|
|
33
|
+
failOnError: true,
|
|
34
|
+
onlyFinal: false
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export class PollResourceAccessor {
|
|
38
|
+
constructor(
|
|
39
|
+
public readonly tx: PollTxAccessor,
|
|
40
|
+
public readonly data: ResourceData,
|
|
41
|
+
public readonly path: string[]
|
|
42
|
+
) {}
|
|
43
|
+
|
|
44
|
+
public final(): PollResourceAccessor {
|
|
45
|
+
if (!this.data.final) throw new ContinuePolling();
|
|
46
|
+
return this;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
public async requireNoError(): Promise<PollResourceAccessor> {
|
|
50
|
+
if (isNullResourceId(this.data.error)) return this;
|
|
51
|
+
await this.tx.throwError(this.data.error, this.path);
|
|
52
|
+
// hmm... https://github.com/microsoft/TypeScript/issues/34955
|
|
53
|
+
return this;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
public getFieldData(name: string, expectedType?: FieldType): FieldData {
|
|
57
|
+
const fieldData = this.data.fields.find((f) => f.name === name);
|
|
58
|
+
|
|
59
|
+
if (fieldData !== undefined) {
|
|
60
|
+
if (expectedType !== undefined && fieldData.type !== expectedType)
|
|
61
|
+
throw new Error(`Unexpected field type. Expected ${expectedType}, found ${fieldData.type}`);
|
|
62
|
+
return fieldData;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (
|
|
66
|
+
((expectedType === 'Input' || expectedType === 'Service') && this.data.inputsLocked) ||
|
|
67
|
+
(expectedType === 'Output' && this.data.outputsLocked)
|
|
68
|
+
)
|
|
69
|
+
throw new Error(
|
|
70
|
+
`Field "${name}" not found. Expected type: ${expectedType}, state: ${this.data}`
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
throw new ContinuePolling();
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
public async get(
|
|
77
|
+
name: string,
|
|
78
|
+
ops: Partial<PollFieldTraverseOps> = {}
|
|
79
|
+
): Promise<PollResourceAccessor> {
|
|
80
|
+
const { expectedType, failOnError, onlyFinal } = { ...DefaultPollFieldTraverseOps, ...ops };
|
|
81
|
+
const path = [...this.path, name];
|
|
82
|
+
|
|
83
|
+
const fieldData = this.getFieldData(name, expectedType);
|
|
84
|
+
if (isNotNullResourceId(fieldData.error) && (failOnError || isNullResourceId(fieldData.value)))
|
|
85
|
+
await this.tx.throwError(fieldData.error, path);
|
|
86
|
+
|
|
87
|
+
if (isNullResourceId(fieldData.value)) throw new ContinuePolling();
|
|
88
|
+
|
|
89
|
+
return await this.tx.get(fieldData.value, failOnError, path);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
public async getMulti(
|
|
93
|
+
ops: Partial<PollFieldTraverseOps>,
|
|
94
|
+
...names: string[]
|
|
95
|
+
): Promise<PollResourceAccessor[]> {
|
|
96
|
+
return await Promise.all(names.map((name) => this.get(name, ops)));
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
public async getMultiObj<Key extends string>(
|
|
100
|
+
ops: Partial<PollFieldTraverseOps>,
|
|
101
|
+
...names: Key[]
|
|
102
|
+
): Promise<Record<Key, PollResourceAccessor>> {
|
|
103
|
+
return Object.fromEntries(
|
|
104
|
+
await Promise.all(names.map(async (name) => [name, await this.get(name, ops)]))
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
public async getAllFinal(
|
|
109
|
+
ops: Partial<PollFieldTraverseOps> = {}
|
|
110
|
+
): Promise<Record<string, PollResourceAccessor>> {
|
|
111
|
+
return await this.getMultiObj(
|
|
112
|
+
ops,
|
|
113
|
+
...this.data.fields
|
|
114
|
+
.filter((f) => f.valueIsFinal || isNotNullResourceId(f.error))
|
|
115
|
+
.map((f) => f.name)
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
public async getKValue(key: string): Promise<string> {
|
|
120
|
+
const value = await this.tx.tx.getKValueStringIfExists(this.data.id, key);
|
|
121
|
+
if (value === undefined) throw new ContinuePolling();
|
|
122
|
+
return value;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
public async getKValueObj<T>(key: string): Promise<T> {
|
|
126
|
+
return JSON.parse(await this.getKValue(key)) as T;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export class PollTxAccessor {
|
|
131
|
+
constructor(public readonly tx: PlTransaction) {}
|
|
132
|
+
|
|
133
|
+
public async get(
|
|
134
|
+
rid: ResourceId,
|
|
135
|
+
failOnError: boolean = true,
|
|
136
|
+
path: string[] = []
|
|
137
|
+
): Promise<PollResourceAccessor> {
|
|
138
|
+
const data = await this.tx.getResourceData(rid, true);
|
|
139
|
+
const accessor = new PollResourceAccessor(this, data, [...path, resourceIdToString(rid)]);
|
|
140
|
+
if (failOnError) await accessor.requireNoError();
|
|
141
|
+
return accessor;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
async throwError(error: ResourceId, path: string[] = []): Promise<never> {
|
|
145
|
+
const errorRes = await this.get(error);
|
|
146
|
+
let errorText = Buffer.from(notEmpty(errorRes.data.data)).toString();
|
|
147
|
+
throw new Error(`${path.join(' -> ')} = ${errorText}`);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export const DefaultPollingRetryOptions: RetryOptions = {
|
|
152
|
+
type: 'linearBackoff',
|
|
153
|
+
jitter: 0,
|
|
154
|
+
maxAttempts: 100,
|
|
155
|
+
backoffStep: 10,
|
|
156
|
+
initialDelay: 10
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
export async function poll<T>(
|
|
160
|
+
cl: PlClient,
|
|
161
|
+
cb: (tx: PollTxAccessor) => Promise<T>,
|
|
162
|
+
retryOptions: RetryOptions = DefaultPollingRetryOptions,
|
|
163
|
+
txName: string = 'polling'
|
|
164
|
+
): Promise<T> {
|
|
165
|
+
let retryState = createRetryState(retryOptions);
|
|
166
|
+
while (true) {
|
|
167
|
+
try {
|
|
168
|
+
return await cl.withReadTx(txName, async (tx) => {
|
|
169
|
+
return await cb(new PollTxAccessor(tx));
|
|
170
|
+
});
|
|
171
|
+
} catch (e: any) {
|
|
172
|
+
// Rethrowing any error except the "not ready yet"
|
|
173
|
+
if (!(e instanceof ContinuePolling)) throw e;
|
|
174
|
+
}
|
|
175
|
+
await tp.setTimeout(retryState.nextDelay);
|
|
176
|
+
retryState = nextRetryStateOrError(retryState);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// type TestType1 = string;
|
|
2
|
+
// type TestType2 = string | number | { a: number };
|
|
3
|
+
//
|
|
4
|
+
// const RichType1 = richResourceType('RichType1', '1');
|
|
5
|
+
//
|
|
6
|
+
// type WithAnyRichType<T> = WithRichType<T, string>
|
|
7
|
+
//
|
|
8
|
+
// function withRichType<RT extends PlResourceType>(t2: TestType2, type: RT): WithRichType<TestType1, RT> {
|
|
9
|
+
// return '' as WithRichType<TestType1, RT>;
|
|
10
|
+
// }
|
|
11
|
+
//
|
|
12
|
+
// function something<RT extends PlResourceType, TT extends WithRichType<TestType1, RT>>(t2: TT): TT
|
|
13
|
+
// // function something(t2: TestType1): TestType1
|
|
14
|
+
// function something(t2: TestType1): TestType1 {
|
|
15
|
+
// return t2;
|
|
16
|
+
// }
|
|
17
|
+
|
|
18
|
+
test('simple test', () => {
|
|
19
|
+
// const t2 = '';
|
|
20
|
+
// const t2a = withRichType(t2, RichType1);
|
|
21
|
+
// const t2c = something(t2a);
|
|
22
|
+
});
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
// import { ResourceType } from './types';
|
|
2
|
+
//
|
|
3
|
+
// //
|
|
4
|
+
// // NOTE: This code is not used.
|
|
5
|
+
// // It shows a raw idea on how to implement typed Tx API
|
|
6
|
+
// //
|
|
7
|
+
//
|
|
8
|
+
// export type AnyStructuralResourceKind = 'structural' | 'ephemeral' | 'singleton'
|
|
9
|
+
// export type ResourceKind = AnyStructuralResourceKind | 'value';
|
|
10
|
+
//
|
|
11
|
+
// declare const __resource_type: unique symbol;
|
|
12
|
+
// export type WithRichType<T, B extends ResourceType> = T & { [__resource_type]: B }
|
|
13
|
+
//
|
|
14
|
+
// export type Serde<V> = {
|
|
15
|
+
// ser: (obj: V) => Uint8Array
|
|
16
|
+
// des: (data: Uint8Array) => V
|
|
17
|
+
// }
|
|
18
|
+
//
|
|
19
|
+
// export type RichResourceType<Kind extends ResourceKind,
|
|
20
|
+
// Name extends string, Version extends string, Value = never> =
|
|
21
|
+
// {
|
|
22
|
+
// kind: Kind,
|
|
23
|
+
// name: Name,
|
|
24
|
+
// version: Version,
|
|
25
|
+
// serde: Serde<Value>
|
|
26
|
+
// }
|
|
27
|
+
//
|
|
28
|
+
// export type AnyStructuralRichResourceType = RichResourceType<AnyStructuralResourceKind, string, string, unknown>
|
|
29
|
+
//
|
|
30
|
+
// const DummySerde: Serde<never> = {
|
|
31
|
+
// ser: (t) => {
|
|
32
|
+
// throw new Error();
|
|
33
|
+
// },
|
|
34
|
+
// des: (t) => {
|
|
35
|
+
// throw new Error();
|
|
36
|
+
// }
|
|
37
|
+
// };
|
|
38
|
+
//
|
|
39
|
+
// const NoSerde = { serde: DummySerde };
|
|
40
|
+
//
|
|
41
|
+
// export function richStructuralType<
|
|
42
|
+
// Name extends string,
|
|
43
|
+
// Version extends string,
|
|
44
|
+
// Kind extends AnyStructuralResourceKind>(
|
|
45
|
+
// kind: Kind,
|
|
46
|
+
// name: Name,
|
|
47
|
+
// version: Version
|
|
48
|
+
// ): RichResourceType<Kind, Name, Version> {
|
|
49
|
+
// return { kind, name, version, ...NoSerde };
|
|
50
|
+
// }
|
|
51
|
+
//
|
|
52
|
+
// export function richValueType<
|
|
53
|
+
// Name extends string,
|
|
54
|
+
// Version extends string,
|
|
55
|
+
// Value>(
|
|
56
|
+
// name: Name,
|
|
57
|
+
// version: Version,
|
|
58
|
+
// serde: Serde<Value>
|
|
59
|
+
// ): RichResourceType<'value', Name, Version, Value> {
|
|
60
|
+
// return { kind: 'value', name, version, serde };
|
|
61
|
+
// }
|
|
62
|
+
//
|
|
63
|
+
// export type RichFieldType<
|
|
64
|
+
// Parent extends AnyStructuralRichResourceType,
|
|
65
|
+
// Name extends string,
|
|
66
|
+
// Ref extends AnyStructuralRichResourceType> =
|
|
67
|
+
// {
|
|
68
|
+
// parent: Parent,
|
|
69
|
+
// name: Name,
|
|
70
|
+
// referenced: Ref
|
|
71
|
+
// }
|
|
72
|
+
//
|
|
73
|
+
// export function richFieldType<
|
|
74
|
+
// Parent extends AnyStructuralRichResourceType,
|
|
75
|
+
// Name extends string,
|
|
76
|
+
// Ref extends AnyStructuralRichResourceType>(
|
|
77
|
+
// parent: Parent,
|
|
78
|
+
// name: Name,
|
|
79
|
+
// referenced: Ref
|
|
80
|
+
// ): RichFieldType<Parent, Name, Ref> {
|
|
81
|
+
// return { parent, name, referenced };
|
|
82
|
+
// }
|
|
83
|
+
//
|
|
84
|
+
// const BContextEnd = richStructuralType('structural', 'BContextEnd', '1');
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
// import { FieldData, isNotNullResourceId, ResourceData, ResourceKind } from '../core/types';
|
|
2
|
+
// import { AnyFieldRef, AnyResourceRef, PlTransaction, ResourceRef } from '../core/transaction';
|
|
3
|
+
// import { notEmpty } from '../util/util';
|
|
4
|
+
//
|
|
5
|
+
// export type Serde<V> = {
|
|
6
|
+
// ser: (obj: V) => Uint8Array
|
|
7
|
+
// des: (data: Uint8Array) => V
|
|
8
|
+
// }
|
|
9
|
+
//
|
|
10
|
+
// const DummySerde: Serde<never> = {
|
|
11
|
+
// ser: () => {
|
|
12
|
+
// throw new Error();
|
|
13
|
+
// },
|
|
14
|
+
// des: () => {
|
|
15
|
+
// throw new Error();
|
|
16
|
+
// }
|
|
17
|
+
// };
|
|
18
|
+
//
|
|
19
|
+
// const NoSerde = { serde: DummySerde };
|
|
20
|
+
//
|
|
21
|
+
// export type StructuralSmartResourceKind = 'structural' | 'ephemeral'
|
|
22
|
+
// export type SmartResourceKind = StructuralSmartResourceKind | 'value'
|
|
23
|
+
//
|
|
24
|
+
// export type SmartResourceType<Kind extends ResourceKind, Name extends string,
|
|
25
|
+
// Version extends string, Value = never> =
|
|
26
|
+
// {
|
|
27
|
+
// kind: Kind,
|
|
28
|
+
// smartKind: SmartResourceKind,
|
|
29
|
+
// name: Name,
|
|
30
|
+
// version: Version,
|
|
31
|
+
// serde: Serde<Value>
|
|
32
|
+
// }
|
|
33
|
+
//
|
|
34
|
+
// export type AnySmartResourceType = SmartResourceType<ResourceKind, string, string, unknown>
|
|
35
|
+
// export type AnyStructuralSmartResourceType = SmartResourceType<'Structural', string, string, unknown>
|
|
36
|
+
//
|
|
37
|
+
// export type SmartFieldType<
|
|
38
|
+
// Parent extends AnyStructuralSmartResourceType,
|
|
39
|
+
// Ref extends AnyStructuralSmartResourceType> =
|
|
40
|
+
// {
|
|
41
|
+
// parent: Parent,
|
|
42
|
+
// name: string,
|
|
43
|
+
// referenced: Ref
|
|
44
|
+
// }
|
|
45
|
+
//
|
|
46
|
+
// export type AnySmartFieldType = SmartFieldType<AnyStructuralSmartResourceType, AnyStructuralSmartResourceType>;
|
|
47
|
+
//
|
|
48
|
+
// export function structuralValueSRT<Name extends string, Version extends string, Value>(
|
|
49
|
+
// smartKind: SmartResourceKind,
|
|
50
|
+
// name: Name,
|
|
51
|
+
// version: Version,
|
|
52
|
+
// serde: Serde<Value>
|
|
53
|
+
// ): SmartResourceType<'Structural', Name, Version, Value> {
|
|
54
|
+
// return { kind: 'Structural', smartKind, name, version, serde };
|
|
55
|
+
// }
|
|
56
|
+
//
|
|
57
|
+
// export function structuralSRT<Name extends string, Version extends string>(
|
|
58
|
+
// smartKind: SmartResourceKind,
|
|
59
|
+
// name: Name,
|
|
60
|
+
// version: Version
|
|
61
|
+
// ): SmartResourceType<'Structural', Name, Version, never> {
|
|
62
|
+
// return { kind: 'Structural', smartKind, name, version, serde: DummySerde };
|
|
63
|
+
// }
|
|
64
|
+
//
|
|
65
|
+
// export function valueSRT<Name extends string, Version extends string, Value>(
|
|
66
|
+
// name: Name,
|
|
67
|
+
// version: Version,
|
|
68
|
+
// serde: Serde<Value>
|
|
69
|
+
// ): SmartResourceType<'Value', Name, Version, Value> {
|
|
70
|
+
// return { kind: 'Value', smartKind: 'value', name, version, serde };
|
|
71
|
+
// }
|
|
72
|
+
//
|
|
73
|
+
// export function smartFields<
|
|
74
|
+
// Parent extends AnyStructuralSmartResourceType,
|
|
75
|
+
// Ref extends AnyStructuralSmartResourceType>(
|
|
76
|
+
// parent: Parent,
|
|
77
|
+
// name: string,
|
|
78
|
+
// referenced: Ref
|
|
79
|
+
// ): SmartFieldType<Parent, Ref> {
|
|
80
|
+
// return { parent, name, referenced };
|
|
81
|
+
// }
|
|
82
|
+
//
|
|
83
|
+
// export type GetValueType<ST extends AnySmartResourceType> =
|
|
84
|
+
// ST extends SmartResourceType<ResourceKind, string, string, infer X> ? X : never
|
|
85
|
+
//
|
|
86
|
+
// export type GetRef<SF extends AnySmartFieldType> =
|
|
87
|
+
// SF extends SmartFieldType<AnyStructuralSmartResourceType, infer X> ? X : never
|
|
88
|
+
//
|
|
89
|
+
// export type GetParent<SF extends AnySmartFieldType> =
|
|
90
|
+
// SF extends SmartFieldType<infer X, AnyStructuralSmartResourceType> ? X : never
|
|
91
|
+
//
|
|
92
|
+
// export class SmartStructuralResourceAccessor<ST extends AnyStructuralSmartResourceType> {
|
|
93
|
+
// constructor(public readonly type: ST,
|
|
94
|
+
// public readonly ref: AnyResourceRef,
|
|
95
|
+
// public readonly tx: PlTransaction) {
|
|
96
|
+
// }
|
|
97
|
+
//
|
|
98
|
+
// private _resourceData?: Promise<ResourceData>;
|
|
99
|
+
//
|
|
100
|
+
// public async getResourceData(): Promise<ResourceData> {
|
|
101
|
+
// if (this._resourceData === undefined)
|
|
102
|
+
// this._resourceData = this.tx.getResourceData(this.ref, true);
|
|
103
|
+
// return await this._resourceData;
|
|
104
|
+
// }
|
|
105
|
+
//
|
|
106
|
+
// public async getValue(): Promise<GetValueType<ST>> {
|
|
107
|
+
// return this.type.serde.des(notEmpty((await this.getResourceData()).data)) as GetValueType<ST>;
|
|
108
|
+
// }
|
|
109
|
+
//
|
|
110
|
+
// public getField<SF extends SmartFieldType<ST, AnyStructuralSmartResourceType>>(field: SF): Promise<GetValueType<ST>> {
|
|
111
|
+
// return new SmartFieldAccessor(field, { resourceId: this.ref, fieldName: field.name }, this.tx);
|
|
112
|
+
// }
|
|
113
|
+
//
|
|
114
|
+
// }
|
|
115
|
+
//
|
|
116
|
+
// export class SmartFieldAccessor<SF extends AnySmartFieldType> {
|
|
117
|
+
// constructor(public readonly descriptor: SF,
|
|
118
|
+
// public readonly ref: AnyFieldRef,
|
|
119
|
+
// public readonly tx: PlTransaction) {
|
|
120
|
+
// }
|
|
121
|
+
//
|
|
122
|
+
// public parent(): SmartStructuralResourceAccessor<GetParent<SF>> {
|
|
123
|
+
// return new SmartStructuralResourceAccessor(
|
|
124
|
+
// this.descriptor.parent as GetParent<SF>,
|
|
125
|
+
// this.ref.resourceId, this.tx);
|
|
126
|
+
// }
|
|
127
|
+
//
|
|
128
|
+
// private _fieldData?: Promise<FieldData>;
|
|
129
|
+
//
|
|
130
|
+
// public async getFieldData(): Promise<FieldData> {
|
|
131
|
+
// if (this._fieldData === undefined)
|
|
132
|
+
// this._fieldData = this.tx.getField(this.ref);
|
|
133
|
+
// return await this._fieldData;
|
|
134
|
+
// }
|
|
135
|
+
//
|
|
136
|
+
//
|
|
137
|
+
// public async get(): SmartStructuralResourceAccessor<GetRef<SF>> {
|
|
138
|
+
// const fieldData = await this.getFieldData();
|
|
139
|
+
// if (isNotNullResourceId(fieldData.error))
|
|
140
|
+
// throw new Error('Error in field.');
|
|
141
|
+
// return new SmartStructuralResourceAccessor(
|
|
142
|
+
// this.descriptor.referenced as GetRef<SF>,
|
|
143
|
+
// fieldData.value,
|
|
144
|
+
// this.tx);
|
|
145
|
+
// }
|
|
146
|
+
// }
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { PlTransaction } from '../core/transaction';
|
|
2
|
+
import { FieldData, OptionalResourceId, isNotNullResourceId } from '../core/types';
|
|
3
|
+
import { notEmpty } from '@milaboratories/ts-helpers';
|
|
4
|
+
|
|
5
|
+
export interface ValErr {
|
|
6
|
+
valueId: OptionalResourceId;
|
|
7
|
+
errorId: OptionalResourceId;
|
|
8
|
+
error?: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export async function valErr(tx: PlTransaction, f: FieldData): Promise<ValErr> {
|
|
12
|
+
const result = {
|
|
13
|
+
valueId: f.value,
|
|
14
|
+
errorId: f.error,
|
|
15
|
+
error: ''
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
if (isNotNullResourceId(f.error)) {
|
|
19
|
+
const e = await tx.getResourceData(f.error, true);
|
|
20
|
+
result.error = JSON.parse(notEmpty(e.data).toString());
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return result;
|
|
24
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export * from './core/types';
|
|
2
|
+
export * as Pl from './helpers/pl';
|
|
3
|
+
export * from './core/config';
|
|
4
|
+
export * from './core/client';
|
|
5
|
+
export * from './core/driver';
|
|
6
|
+
export * from './core/transaction';
|
|
7
|
+
export * from './core/errors';
|
|
8
|
+
export * from './core/default_client';
|
|
9
|
+
export * from './core/unauth_client';
|
|
10
|
+
export * from './core/auth';
|
|
11
|
+
export * from './helpers/tx_helpers';
|
|
12
|
+
export * from './helpers/poll';
|
|
13
|
+
|
|
14
|
+
export * as TestHelpers from './test/test_config';
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
// @generated by protobuf-ts 2.9.4 with parameter client_generic,optimize_speed,generate_dependencies,force_server_none
|
|
2
|
+
// @generated from protobuf file "github.com/googleapis/googleapis/google/rpc/status.proto" (package "google.rpc", syntax proto3)
|
|
3
|
+
// tslint:disable
|
|
4
|
+
//
|
|
5
|
+
// Copyright 2020 Google LLC
|
|
6
|
+
//
|
|
7
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
|
+
// you may not use this file except in compliance with the License.
|
|
9
|
+
// You may obtain a copy of the License at
|
|
10
|
+
//
|
|
11
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
//
|
|
13
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
// See the License for the specific language governing permissions and
|
|
17
|
+
// limitations under the License.
|
|
18
|
+
//
|
|
19
|
+
import type { BinaryWriteOptions } from "@protobuf-ts/runtime";
|
|
20
|
+
import type { IBinaryWriter } from "@protobuf-ts/runtime";
|
|
21
|
+
import { WireType } from "@protobuf-ts/runtime";
|
|
22
|
+
import type { BinaryReadOptions } from "@protobuf-ts/runtime";
|
|
23
|
+
import type { IBinaryReader } from "@protobuf-ts/runtime";
|
|
24
|
+
import { UnknownFieldHandler } from "@protobuf-ts/runtime";
|
|
25
|
+
import type { PartialMessage } from "@protobuf-ts/runtime";
|
|
26
|
+
import { reflectionMergePartial } from "@protobuf-ts/runtime";
|
|
27
|
+
import { MessageType } from "@protobuf-ts/runtime";
|
|
28
|
+
import { Any } from "../../../../../google/protobuf/any";
|
|
29
|
+
/**
|
|
30
|
+
* The `Status` type defines a logical error model that is suitable for
|
|
31
|
+
* different programming environments, including REST APIs and RPC APIs. It is
|
|
32
|
+
* used by [gRPC](https://github.com/grpc). Each `Status` message contains
|
|
33
|
+
* three pieces of data: error code, error message, and error details.
|
|
34
|
+
*
|
|
35
|
+
* You can find out more about this error model and how to work with it in the
|
|
36
|
+
* [API Design Guide](https://cloud.google.com/apis/design/errors).
|
|
37
|
+
*
|
|
38
|
+
* @generated from protobuf message google.rpc.Status
|
|
39
|
+
*/
|
|
40
|
+
export interface Status {
|
|
41
|
+
/**
|
|
42
|
+
* The status code, which should be an enum value of [google.rpc.Code][google.rpc.Code].
|
|
43
|
+
*
|
|
44
|
+
* @generated from protobuf field: int32 code = 1;
|
|
45
|
+
*/
|
|
46
|
+
code: number;
|
|
47
|
+
/**
|
|
48
|
+
* A developer-facing error message, which should be in English. Any
|
|
49
|
+
* user-facing error message should be localized and sent in the
|
|
50
|
+
* [google.rpc.Status.details][google.rpc.Status.details] field, or localized by the client.
|
|
51
|
+
*
|
|
52
|
+
* @generated from protobuf field: string message = 2;
|
|
53
|
+
*/
|
|
54
|
+
message: string;
|
|
55
|
+
/**
|
|
56
|
+
* A list of messages that carry the error details. There is a common set of
|
|
57
|
+
* message types for APIs to use.
|
|
58
|
+
*
|
|
59
|
+
* @generated from protobuf field: repeated google.protobuf.Any details = 3;
|
|
60
|
+
*/
|
|
61
|
+
details: Any[];
|
|
62
|
+
}
|
|
63
|
+
// @generated message type with reflection information, may provide speed optimized methods
|
|
64
|
+
class Status$Type extends MessageType<Status> {
|
|
65
|
+
constructor() {
|
|
66
|
+
super("google.rpc.Status", [
|
|
67
|
+
{ no: 1, name: "code", kind: "scalar", T: 5 /*ScalarType.INT32*/ },
|
|
68
|
+
{ no: 2, name: "message", kind: "scalar", T: 9 /*ScalarType.STRING*/ },
|
|
69
|
+
{ no: 3, name: "details", kind: "message", repeat: 1 /*RepeatType.PACKED*/, T: () => Any }
|
|
70
|
+
]);
|
|
71
|
+
}
|
|
72
|
+
create(value?: PartialMessage<Status>): Status {
|
|
73
|
+
const message = globalThis.Object.create((this.messagePrototype!));
|
|
74
|
+
message.code = 0;
|
|
75
|
+
message.message = "";
|
|
76
|
+
message.details = [];
|
|
77
|
+
if (value !== undefined)
|
|
78
|
+
reflectionMergePartial<Status>(this, message, value);
|
|
79
|
+
return message;
|
|
80
|
+
}
|
|
81
|
+
internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: Status): Status {
|
|
82
|
+
let message = target ?? this.create(), end = reader.pos + length;
|
|
83
|
+
while (reader.pos < end) {
|
|
84
|
+
let [fieldNo, wireType] = reader.tag();
|
|
85
|
+
switch (fieldNo) {
|
|
86
|
+
case /* int32 code */ 1:
|
|
87
|
+
message.code = reader.int32();
|
|
88
|
+
break;
|
|
89
|
+
case /* string message */ 2:
|
|
90
|
+
message.message = reader.string();
|
|
91
|
+
break;
|
|
92
|
+
case /* repeated google.protobuf.Any details */ 3:
|
|
93
|
+
message.details.push(Any.internalBinaryRead(reader, reader.uint32(), options));
|
|
94
|
+
break;
|
|
95
|
+
default:
|
|
96
|
+
let u = options.readUnknownField;
|
|
97
|
+
if (u === "throw")
|
|
98
|
+
throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`);
|
|
99
|
+
let d = reader.skip(wireType);
|
|
100
|
+
if (u !== false)
|
|
101
|
+
(u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return message;
|
|
105
|
+
}
|
|
106
|
+
internalBinaryWrite(message: Status, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter {
|
|
107
|
+
/* int32 code = 1; */
|
|
108
|
+
if (message.code !== 0)
|
|
109
|
+
writer.tag(1, WireType.Varint).int32(message.code);
|
|
110
|
+
/* string message = 2; */
|
|
111
|
+
if (message.message !== "")
|
|
112
|
+
writer.tag(2, WireType.LengthDelimited).string(message.message);
|
|
113
|
+
/* repeated google.protobuf.Any details = 3; */
|
|
114
|
+
for (let i = 0; i < message.details.length; i++)
|
|
115
|
+
Any.internalBinaryWrite(message.details[i], writer.tag(3, WireType.LengthDelimited).fork(), options).join();
|
|
116
|
+
let u = options.writeUnknownFields;
|
|
117
|
+
if (u !== false)
|
|
118
|
+
(u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
|
|
119
|
+
return writer;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* @generated MessageType for protobuf message google.rpc.Status
|
|
124
|
+
*/
|
|
125
|
+
export const Status = new Status$Type();
|
package/src/proto/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.client.ts
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// @generated by protobuf-ts 2.9.4 with parameter client_generic,optimize_speed,generate_dependencies,force_server_none
|
|
2
|
+
// @generated from protobuf file "github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.proto" (package "MiLaboratories.Controller.Shared", syntax proto3)
|
|
3
|
+
// tslint:disable
|
|
4
|
+
import type { RpcTransport } from "@protobuf-ts/runtime-rpc";
|
|
5
|
+
import type { ServiceInfo } from "@protobuf-ts/runtime-rpc";
|
|
6
|
+
import { Download } from "./protocol";
|
|
7
|
+
import { stackIntercept } from "@protobuf-ts/runtime-rpc";
|
|
8
|
+
import type { DownloadAPI_GetDownloadURL_Response } from "./protocol";
|
|
9
|
+
import type { DownloadAPI_GetDownloadURL_Request } from "./protocol";
|
|
10
|
+
import type { UnaryCall } from "@protobuf-ts/runtime-rpc";
|
|
11
|
+
import type { RpcOptions } from "@protobuf-ts/runtime-rpc";
|
|
12
|
+
/**
|
|
13
|
+
*
|
|
14
|
+
* Download provides access to any data, that can be downloaded via network.
|
|
15
|
+
*
|
|
16
|
+
*
|
|
17
|
+
* @generated from protobuf service MiLaboratories.Controller.Shared.Download
|
|
18
|
+
*/
|
|
19
|
+
export interface IDownloadClient {
|
|
20
|
+
/**
|
|
21
|
+
* @generated from protobuf rpc: GetDownloadURL(MiLaboratories.Controller.Shared.DownloadAPI.GetDownloadURL.Request) returns (MiLaboratories.Controller.Shared.DownloadAPI.GetDownloadURL.Response);
|
|
22
|
+
*/
|
|
23
|
+
getDownloadURL(input: DownloadAPI_GetDownloadURL_Request, options?: RpcOptions): UnaryCall<DownloadAPI_GetDownloadURL_Request, DownloadAPI_GetDownloadURL_Response>;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
*
|
|
27
|
+
* Download provides access to any data, that can be downloaded via network.
|
|
28
|
+
*
|
|
29
|
+
*
|
|
30
|
+
* @generated from protobuf service MiLaboratories.Controller.Shared.Download
|
|
31
|
+
*/
|
|
32
|
+
export class DownloadClient implements IDownloadClient, ServiceInfo {
|
|
33
|
+
typeName = Download.typeName;
|
|
34
|
+
methods = Download.methods;
|
|
35
|
+
options = Download.options;
|
|
36
|
+
constructor(private readonly _transport: RpcTransport) {
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* @generated from protobuf rpc: GetDownloadURL(MiLaboratories.Controller.Shared.DownloadAPI.GetDownloadURL.Request) returns (MiLaboratories.Controller.Shared.DownloadAPI.GetDownloadURL.Response);
|
|
40
|
+
*/
|
|
41
|
+
getDownloadURL(input: DownloadAPI_GetDownloadURL_Request, options?: RpcOptions): UnaryCall<DownloadAPI_GetDownloadURL_Request, DownloadAPI_GetDownloadURL_Response> {
|
|
42
|
+
const method = this.methods[0], opt = this._transport.mergeOptions(options);
|
|
43
|
+
return stackIntercept<DownloadAPI_GetDownloadURL_Request, DownloadAPI_GetDownloadURL_Response>("unary", this._transport, method, opt, input);
|
|
44
|
+
}
|
|
45
|
+
}
|