@valon-technologies/gestalt 0.0.1-alpha.8 → 0.0.1-alpha.9
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 +8 -10
- package/gen/v1/{auth_pb.ts → authentication_pb.ts} +51 -17
- package/gen/v1/authorization_pb.ts +857 -0
- package/gen/v1/cache_pb.ts +32 -0
- package/gen/v1/datastore_pb.ts +62 -0
- package/gen/v1/plugin_pb.ts +216 -18
- package/gen/v1/runtime_pb.ts +27 -3
- package/gen/v1/s3_pb.ts +39 -0
- package/gen/v1/secrets_pb.ts +6 -0
- package/gen/v1/workflow_pb.ts +1372 -0
- package/package.json +9 -1
- package/src/api.ts +56 -0
- package/src/auth.ts +67 -16
- package/src/build.ts +37 -21
- package/src/cache.ts +32 -0
- package/src/catalog.ts +27 -0
- package/src/index.ts +87 -18
- package/src/indexeddb.ts +166 -0
- package/src/invoker.ts +124 -0
- package/src/plugin.ts +93 -38
- package/src/provider-kind.ts +107 -0
- package/src/provider.ts +32 -1
- package/src/runtime.ts +233 -218
- package/src/s3.ts +135 -20
- package/src/schema.ts +46 -0
- package/src/secrets.ts +12 -0
- package/src/target.ts +58 -60
- package/src/workflow-manager.ts +131 -0
- package/src/workflow.ts +479 -0
- package/tsconfig.json +1 -0
package/src/s3.ts
CHANGED
|
@@ -28,12 +28,18 @@ const ENV_S3_SOCKET = "GESTALT_S3_SOCKET";
|
|
|
28
28
|
const WRITE_CHUNK_SIZE = 64 * 1024;
|
|
29
29
|
const textEncoder = new TextEncoder();
|
|
30
30
|
|
|
31
|
+
/**
|
|
32
|
+
* Returns the environment variable name used to discover an S3 socket.
|
|
33
|
+
*/
|
|
31
34
|
export function s3SocketEnv(name?: string): string {
|
|
32
35
|
const trimmed = name?.trim() ?? "";
|
|
33
36
|
if (!trimmed) return ENV_S3_SOCKET;
|
|
34
37
|
return `${ENV_S3_SOCKET}_${trimmed.replace(/[^A-Za-z0-9]/g, "_").toUpperCase()}`;
|
|
35
38
|
}
|
|
36
39
|
|
|
40
|
+
/**
|
|
41
|
+
* Error returned when an object reference does not exist.
|
|
42
|
+
*/
|
|
37
43
|
export class S3NotFoundError extends Error {
|
|
38
44
|
constructor(message?: string) {
|
|
39
45
|
super(message ?? "s3: not found");
|
|
@@ -41,6 +47,9 @@ export class S3NotFoundError extends Error {
|
|
|
41
47
|
}
|
|
42
48
|
}
|
|
43
49
|
|
|
50
|
+
/**
|
|
51
|
+
* Error returned when conditional read or write preconditions fail.
|
|
52
|
+
*/
|
|
44
53
|
export class S3PreconditionFailedError extends Error {
|
|
45
54
|
constructor(message?: string) {
|
|
46
55
|
super(message ?? "s3: precondition failed");
|
|
@@ -48,6 +57,9 @@ export class S3PreconditionFailedError extends Error {
|
|
|
48
57
|
}
|
|
49
58
|
}
|
|
50
59
|
|
|
60
|
+
/**
|
|
61
|
+
* Error returned when the requested byte range is invalid.
|
|
62
|
+
*/
|
|
51
63
|
export class S3InvalidRangeError extends Error {
|
|
52
64
|
constructor(message?: string) {
|
|
53
65
|
super(message ?? "s3: invalid range");
|
|
@@ -55,12 +67,18 @@ export class S3InvalidRangeError extends Error {
|
|
|
55
67
|
}
|
|
56
68
|
}
|
|
57
69
|
|
|
70
|
+
/**
|
|
71
|
+
* Identifies a concrete object or object version.
|
|
72
|
+
*/
|
|
58
73
|
export interface ObjectRef {
|
|
59
74
|
bucket: string;
|
|
60
75
|
key: string;
|
|
61
76
|
versionId?: string;
|
|
62
77
|
}
|
|
63
78
|
|
|
79
|
+
/**
|
|
80
|
+
* Metadata returned for an S3 object.
|
|
81
|
+
*/
|
|
64
82
|
export interface ObjectMeta {
|
|
65
83
|
ref: ObjectRef;
|
|
66
84
|
etag: string;
|
|
@@ -71,11 +89,17 @@ export interface ObjectMeta {
|
|
|
71
89
|
storageClass: string;
|
|
72
90
|
}
|
|
73
91
|
|
|
92
|
+
/**
|
|
93
|
+
* Byte range for partial object reads.
|
|
94
|
+
*/
|
|
74
95
|
export interface ByteRange {
|
|
75
96
|
start?: number | bigint;
|
|
76
97
|
end?: number | bigint;
|
|
77
98
|
}
|
|
78
99
|
|
|
100
|
+
/**
|
|
101
|
+
* Conditional and range options for reads.
|
|
102
|
+
*/
|
|
79
103
|
export interface ReadOptions {
|
|
80
104
|
range?: ByteRange;
|
|
81
105
|
ifMatch?: string;
|
|
@@ -84,6 +108,9 @@ export interface ReadOptions {
|
|
|
84
108
|
ifUnmodifiedSince?: Date;
|
|
85
109
|
}
|
|
86
110
|
|
|
111
|
+
/**
|
|
112
|
+
* Optional headers and conditions for writes.
|
|
113
|
+
*/
|
|
87
114
|
export interface WriteOptions {
|
|
88
115
|
contentType?: string;
|
|
89
116
|
cacheControl?: string;
|
|
@@ -95,6 +122,9 @@ export interface WriteOptions {
|
|
|
95
122
|
ifNoneMatch?: string;
|
|
96
123
|
}
|
|
97
124
|
|
|
125
|
+
/**
|
|
126
|
+
* Listing options for object pagination and prefix filtering.
|
|
127
|
+
*/
|
|
98
128
|
export interface ListOptions {
|
|
99
129
|
bucket: string;
|
|
100
130
|
prefix?: string;
|
|
@@ -104,6 +134,9 @@ export interface ListOptions {
|
|
|
104
134
|
maxKeys?: number;
|
|
105
135
|
}
|
|
106
136
|
|
|
137
|
+
/**
|
|
138
|
+
* Single page of results returned by {@link S3.listObjects}.
|
|
139
|
+
*/
|
|
107
140
|
export interface ListPage {
|
|
108
141
|
objects: ObjectMeta[];
|
|
109
142
|
commonPrefixes: string[];
|
|
@@ -111,11 +144,17 @@ export interface ListPage {
|
|
|
111
144
|
hasMore: boolean;
|
|
112
145
|
}
|
|
113
146
|
|
|
147
|
+
/**
|
|
148
|
+
* Conditional options for server-side copy operations.
|
|
149
|
+
*/
|
|
114
150
|
export interface CopyOptions {
|
|
115
151
|
ifMatch?: string;
|
|
116
152
|
ifNoneMatch?: string;
|
|
117
153
|
}
|
|
118
154
|
|
|
155
|
+
/**
|
|
156
|
+
* Supported presign methods.
|
|
157
|
+
*/
|
|
119
158
|
export enum PresignMethod {
|
|
120
159
|
Get = "GET",
|
|
121
160
|
Put = "PUT",
|
|
@@ -123,6 +162,9 @@ export enum PresignMethod {
|
|
|
123
162
|
Head = "HEAD",
|
|
124
163
|
}
|
|
125
164
|
|
|
165
|
+
/**
|
|
166
|
+
* Options used when generating a presigned URL.
|
|
167
|
+
*/
|
|
126
168
|
export interface PresignOptions {
|
|
127
169
|
method?: PresignMethod;
|
|
128
170
|
expiresSeconds?: number | bigint;
|
|
@@ -131,6 +173,9 @@ export interface PresignOptions {
|
|
|
131
173
|
headers?: Record<string, string>;
|
|
132
174
|
}
|
|
133
175
|
|
|
176
|
+
/**
|
|
177
|
+
* Result returned by {@link S3.presignObject} or {@link S3Object.presign}.
|
|
178
|
+
*/
|
|
134
179
|
export interface PresignResult {
|
|
135
180
|
url: string;
|
|
136
181
|
method: PresignMethod;
|
|
@@ -138,6 +183,9 @@ export interface PresignResult {
|
|
|
138
183
|
headers: Record<string, string>;
|
|
139
184
|
}
|
|
140
185
|
|
|
186
|
+
/**
|
|
187
|
+
* Accepted write body sources for the S3 client.
|
|
188
|
+
*/
|
|
141
189
|
export type S3BodySource =
|
|
142
190
|
| string
|
|
143
191
|
| Uint8Array
|
|
@@ -149,16 +197,25 @@ export type S3BodySource =
|
|
|
149
197
|
| null
|
|
150
198
|
| undefined;
|
|
151
199
|
|
|
200
|
+
/**
|
|
201
|
+
* Streaming read result returned by the S3 client.
|
|
202
|
+
*/
|
|
152
203
|
export interface ReadResult {
|
|
153
204
|
meta: ObjectMeta;
|
|
154
205
|
stream: AsyncIterable<Uint8Array>;
|
|
155
206
|
}
|
|
156
207
|
|
|
208
|
+
/**
|
|
209
|
+
* Result returned by an authored S3 provider implementation.
|
|
210
|
+
*/
|
|
157
211
|
export interface ProviderReadResult {
|
|
158
212
|
meta: ObjectMeta;
|
|
159
213
|
body?: S3BodySource;
|
|
160
214
|
}
|
|
161
215
|
|
|
216
|
+
/**
|
|
217
|
+
* Runtime hooks required to implement a Gestalt S3 provider.
|
|
218
|
+
*/
|
|
162
219
|
export interface S3ProviderOptions extends RuntimeProviderOptions {
|
|
163
220
|
headObject: (ref: ObjectRef) => MaybePromise<ObjectMeta>;
|
|
164
221
|
readObject: (ref: ObjectRef, options?: ReadOptions) => MaybePromise<ProviderReadResult>;
|
|
@@ -180,6 +237,9 @@ export interface S3ProviderOptions extends RuntimeProviderOptions {
|
|
|
180
237
|
) => MaybePromise<PresignResult>;
|
|
181
238
|
}
|
|
182
239
|
|
|
240
|
+
/**
|
|
241
|
+
* S3 provider implementation consumed by the Gestalt runtime.
|
|
242
|
+
*/
|
|
183
243
|
export class S3Provider extends RuntimeProvider {
|
|
184
244
|
readonly kind = "s3" as const;
|
|
185
245
|
|
|
@@ -239,10 +299,16 @@ export class S3Provider extends RuntimeProvider {
|
|
|
239
299
|
}
|
|
240
300
|
}
|
|
241
301
|
|
|
302
|
+
/**
|
|
303
|
+
* Creates an S3 provider from standard object storage handlers.
|
|
304
|
+
*/
|
|
242
305
|
export function defineS3Provider(options: S3ProviderOptions): S3Provider {
|
|
243
306
|
return new S3Provider(options);
|
|
244
307
|
}
|
|
245
308
|
|
|
309
|
+
/**
|
|
310
|
+
* Runtime type guard for S3 providers loaded from user modules.
|
|
311
|
+
*/
|
|
246
312
|
export function isS3Provider(value: unknown): value is S3Provider {
|
|
247
313
|
return (
|
|
248
314
|
value instanceof S3Provider ||
|
|
@@ -260,6 +326,11 @@ export function isS3Provider(value: unknown): value is S3Provider {
|
|
|
260
326
|
);
|
|
261
327
|
}
|
|
262
328
|
|
|
329
|
+
/**
|
|
330
|
+
* Adapts an authored S3 provider to the shared protocol service implementation.
|
|
331
|
+
*
|
|
332
|
+
* @internal
|
|
333
|
+
*/
|
|
263
334
|
export function createS3Service(
|
|
264
335
|
provider: S3Provider,
|
|
265
336
|
): Partial<ServiceImpl<typeof S3Service>> {
|
|
@@ -411,6 +482,17 @@ export function createS3Service(
|
|
|
411
482
|
};
|
|
412
483
|
}
|
|
413
484
|
|
|
485
|
+
/**
|
|
486
|
+
* Client for invoking a host-provided S3 service over the Gestalt transport.
|
|
487
|
+
*
|
|
488
|
+
* @example
|
|
489
|
+
* ```ts
|
|
490
|
+
* import { S3 } from "@valon-technologies/gestalt";
|
|
491
|
+
*
|
|
492
|
+
* const s3 = new S3();
|
|
493
|
+
* await s3.object("example-bucket", "hello.json").writeJSON({ ok: true });
|
|
494
|
+
* ```
|
|
495
|
+
*/
|
|
414
496
|
export class S3 {
|
|
415
497
|
private readonly client: Client<typeof S3Service>;
|
|
416
498
|
|
|
@@ -467,9 +549,10 @@ export class S3 {
|
|
|
467
549
|
body?: S3BodySource,
|
|
468
550
|
options?: WriteOptions,
|
|
469
551
|
): Promise<ObjectMeta> {
|
|
470
|
-
const
|
|
552
|
+
const byteBody = asS3ByteArray(body);
|
|
553
|
+
const preparedBody = byteBody ? cloneBytes(byteBody) : body;
|
|
471
554
|
const response = await s3Rpc(() =>
|
|
472
|
-
this.client.writeObject(writeRequests(ref,
|
|
555
|
+
this.client.writeObject(writeRequests(ref, preparedBody, options)),
|
|
473
556
|
);
|
|
474
557
|
return fromProtoObjectMeta(response.meta);
|
|
475
558
|
}
|
|
@@ -543,16 +626,25 @@ export class S3 {
|
|
|
543
626
|
}
|
|
544
627
|
}
|
|
545
628
|
|
|
629
|
+
/**
|
|
630
|
+
* Convenience wrapper for working with a single S3 object reference.
|
|
631
|
+
*/
|
|
546
632
|
export class S3Object {
|
|
547
633
|
constructor(
|
|
548
634
|
private readonly client: S3,
|
|
549
635
|
readonly ref: ObjectRef,
|
|
550
636
|
) {}
|
|
551
637
|
|
|
638
|
+
/**
|
|
639
|
+
* Loads object metadata without downloading the object body.
|
|
640
|
+
*/
|
|
552
641
|
async stat(): Promise<ObjectMeta> {
|
|
553
642
|
return await this.client.headObject(this.ref);
|
|
554
643
|
}
|
|
555
644
|
|
|
645
|
+
/**
|
|
646
|
+
* Returns `true` when the referenced object exists.
|
|
647
|
+
*/
|
|
556
648
|
async exists(): Promise<boolean> {
|
|
557
649
|
try {
|
|
558
650
|
await this.stat();
|
|
@@ -565,40 +657,67 @@ export class S3Object {
|
|
|
565
657
|
}
|
|
566
658
|
}
|
|
567
659
|
|
|
660
|
+
/**
|
|
661
|
+
* Reads an object and returns its metadata and byte stream.
|
|
662
|
+
*/
|
|
568
663
|
async read(options?: ReadOptions): Promise<ReadResult> {
|
|
569
664
|
return await this.client.readObject(this.ref, options);
|
|
570
665
|
}
|
|
571
666
|
|
|
667
|
+
/**
|
|
668
|
+
* Reads only the object byte stream.
|
|
669
|
+
*/
|
|
572
670
|
async stream(options?: ReadOptions): Promise<AsyncIterable<Uint8Array>> {
|
|
573
671
|
const result = await this.read(options);
|
|
574
672
|
return result.stream;
|
|
575
673
|
}
|
|
576
674
|
|
|
675
|
+
/**
|
|
676
|
+
* Reads an object into memory as bytes.
|
|
677
|
+
*/
|
|
577
678
|
async bytes(options?: ReadOptions): Promise<Uint8Array> {
|
|
578
679
|
const result = await this.read(options);
|
|
579
680
|
return await collectBytes(result.stream);
|
|
580
681
|
}
|
|
581
682
|
|
|
683
|
+
/**
|
|
684
|
+
* Reads an object into memory as a string.
|
|
685
|
+
*/
|
|
582
686
|
async text(options?: ReadOptions, encoding = "utf-8"): Promise<string> {
|
|
583
687
|
return new TextDecoder(encoding).decode(await this.bytes(options));
|
|
584
688
|
}
|
|
585
689
|
|
|
690
|
+
/**
|
|
691
|
+
* Reads and parses an object as JSON.
|
|
692
|
+
*/
|
|
586
693
|
async json<T = unknown>(options?: ReadOptions): Promise<T> {
|
|
587
694
|
return JSON.parse(await this.text(options)) as T;
|
|
588
695
|
}
|
|
589
696
|
|
|
697
|
+
/**
|
|
698
|
+
* Writes an object body to storage.
|
|
699
|
+
*/
|
|
590
700
|
async write(body?: S3BodySource, options?: WriteOptions): Promise<ObjectMeta> {
|
|
591
701
|
return await this.client.writeObject(this.ref, body, options);
|
|
592
702
|
}
|
|
593
703
|
|
|
704
|
+
/**
|
|
705
|
+
* Writes binary content to storage.
|
|
706
|
+
*/
|
|
594
707
|
async writeBytes(body: Uint8Array | ArrayBuffer | ArrayBufferView): Promise<ObjectMeta> {
|
|
595
708
|
return await this.write(body);
|
|
596
709
|
}
|
|
597
710
|
|
|
711
|
+
/**
|
|
712
|
+
* Writes string content to storage.
|
|
713
|
+
*/
|
|
598
714
|
async writeString(body: string, options?: WriteOptions): Promise<ObjectMeta> {
|
|
599
715
|
return await this.write(body, options);
|
|
600
716
|
}
|
|
601
717
|
|
|
718
|
+
/**
|
|
719
|
+
* Writes JSON content using `application/json` by default.
|
|
720
|
+
*/
|
|
602
721
|
async writeJSON(value: unknown, options: WriteOptions = {}): Promise<ObjectMeta> {
|
|
603
722
|
return await this.write(JSON.stringify(value), {
|
|
604
723
|
...options,
|
|
@@ -606,10 +725,16 @@ export class S3Object {
|
|
|
606
725
|
});
|
|
607
726
|
}
|
|
608
727
|
|
|
728
|
+
/**
|
|
729
|
+
* Deletes the referenced object.
|
|
730
|
+
*/
|
|
609
731
|
async delete(): Promise<void> {
|
|
610
732
|
await this.client.deleteObject(this.ref);
|
|
611
733
|
}
|
|
612
734
|
|
|
735
|
+
/**
|
|
736
|
+
* Generates a presigned URL for the referenced object.
|
|
737
|
+
*/
|
|
613
738
|
async presign(options?: PresignOptions): Promise<PresignResult> {
|
|
614
739
|
return await this.client.presignObject(this.ref, options);
|
|
615
740
|
}
|
|
@@ -755,16 +880,9 @@ async function* toAsyncByteStream(body?: S3BodySource): AsyncIterable<Uint8Array
|
|
|
755
880
|
yield* chunkBytes(textEncoder.encode(body));
|
|
756
881
|
return;
|
|
757
882
|
}
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
}
|
|
762
|
-
if (body instanceof ArrayBuffer) {
|
|
763
|
-
yield* chunkBytes(new Uint8Array(body));
|
|
764
|
-
return;
|
|
765
|
-
}
|
|
766
|
-
if (ArrayBuffer.isView(body)) {
|
|
767
|
-
yield* chunkBytes(new Uint8Array(body.buffer, body.byteOffset, body.byteLength));
|
|
883
|
+
const bytes = asS3ByteArray(body);
|
|
884
|
+
if (bytes) {
|
|
885
|
+
yield* chunkBytes(bytes);
|
|
768
886
|
return;
|
|
769
887
|
}
|
|
770
888
|
if (body instanceof Blob) {
|
|
@@ -790,20 +908,17 @@ function* chunkBytes(bytes: Uint8Array): Iterable<Uint8Array> {
|
|
|
790
908
|
}
|
|
791
909
|
}
|
|
792
910
|
|
|
793
|
-
function
|
|
794
|
-
if (body == null || typeof body === "string") {
|
|
795
|
-
return body;
|
|
796
|
-
}
|
|
911
|
+
function asS3ByteArray(body?: S3BodySource): Uint8Array | undefined {
|
|
797
912
|
if (body instanceof Uint8Array) {
|
|
798
|
-
return
|
|
913
|
+
return body;
|
|
799
914
|
}
|
|
800
915
|
if (body instanceof ArrayBuffer) {
|
|
801
|
-
return body
|
|
916
|
+
return new Uint8Array(body);
|
|
802
917
|
}
|
|
803
918
|
if (ArrayBuffer.isView(body)) {
|
|
804
|
-
return new Uint8Array(body.buffer
|
|
919
|
+
return new Uint8Array(body.buffer, body.byteOffset, body.byteLength);
|
|
805
920
|
}
|
|
806
|
-
return
|
|
921
|
+
return undefined;
|
|
807
922
|
}
|
|
808
923
|
|
|
809
924
|
async function* readableStreamToAsyncIterable(
|
package/src/schema.ts
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Catalog schema kinds supported by the TypeScript SDK.
|
|
3
|
+
*/
|
|
1
4
|
export type CatalogType = "string" | "integer" | "number" | "boolean" | "object" | "array";
|
|
2
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Runtime schema that validates operation input and output values.
|
|
8
|
+
*/
|
|
3
9
|
export interface Schema<T> {
|
|
4
10
|
readonly catalogType: CatalogType;
|
|
5
11
|
readonly description: string;
|
|
@@ -10,10 +16,16 @@ export interface Schema<T> {
|
|
|
10
16
|
parse(value: unknown, path?: string): T;
|
|
11
17
|
}
|
|
12
18
|
|
|
19
|
+
/**
|
|
20
|
+
* Extracts the TypeScript type represented by a {@link Schema}.
|
|
21
|
+
*/
|
|
13
22
|
export type InferSchema<TSchema extends Schema<unknown>> = TSchema extends Schema<infer T>
|
|
14
23
|
? T
|
|
15
24
|
: never;
|
|
16
25
|
|
|
26
|
+
/**
|
|
27
|
+
* Shared options supported by all schema builders.
|
|
28
|
+
*/
|
|
17
29
|
export interface SchemaOptions<T> {
|
|
18
30
|
description?: string;
|
|
19
31
|
required?: boolean;
|
|
@@ -53,6 +65,9 @@ function withMeta<T>(
|
|
|
53
65
|
};
|
|
54
66
|
}
|
|
55
67
|
|
|
68
|
+
/**
|
|
69
|
+
* Creates a string schema.
|
|
70
|
+
*/
|
|
56
71
|
export function string(options?: SchemaOptions<string>): Schema<string> {
|
|
57
72
|
return withMeta(
|
|
58
73
|
"string",
|
|
@@ -66,6 +81,9 @@ export function string(options?: SchemaOptions<string>): Schema<string> {
|
|
|
66
81
|
);
|
|
67
82
|
}
|
|
68
83
|
|
|
84
|
+
/**
|
|
85
|
+
* Creates an integer schema.
|
|
86
|
+
*/
|
|
69
87
|
export function integer(options?: SchemaOptions<number>): Schema<number> {
|
|
70
88
|
return withMeta(
|
|
71
89
|
"integer",
|
|
@@ -85,6 +103,9 @@ export function integer(options?: SchemaOptions<number>): Schema<number> {
|
|
|
85
103
|
);
|
|
86
104
|
}
|
|
87
105
|
|
|
106
|
+
/**
|
|
107
|
+
* Creates a floating-point or integer number schema.
|
|
108
|
+
*/
|
|
88
109
|
export function number(options?: SchemaOptions<number>): Schema<number> {
|
|
89
110
|
return withMeta(
|
|
90
111
|
"number",
|
|
@@ -107,6 +128,9 @@ export function number(options?: SchemaOptions<number>): Schema<number> {
|
|
|
107
128
|
);
|
|
108
129
|
}
|
|
109
130
|
|
|
131
|
+
/**
|
|
132
|
+
* Creates a boolean schema that accepts `true` / `false` and `1` / `0`.
|
|
133
|
+
*/
|
|
110
134
|
export function boolean(options?: SchemaOptions<boolean>): Schema<boolean> {
|
|
111
135
|
return withMeta(
|
|
112
136
|
"boolean",
|
|
@@ -129,6 +153,9 @@ export function boolean(options?: SchemaOptions<boolean>): Schema<boolean> {
|
|
|
129
153
|
);
|
|
130
154
|
}
|
|
131
155
|
|
|
156
|
+
/**
|
|
157
|
+
* Creates an array schema for repeated values.
|
|
158
|
+
*/
|
|
132
159
|
export function array<T>(item: Schema<T>, options?: SchemaOptions<T[]>): Schema<T[]> {
|
|
133
160
|
const base = withMeta<T[]>(
|
|
134
161
|
"array",
|
|
@@ -147,6 +174,19 @@ export function array<T>(item: Schema<T>, options?: SchemaOptions<T[]>): Schema<
|
|
|
147
174
|
};
|
|
148
175
|
}
|
|
149
176
|
|
|
177
|
+
/**
|
|
178
|
+
* Creates an object schema from a field map.
|
|
179
|
+
*
|
|
180
|
+
* @example
|
|
181
|
+
* ```ts
|
|
182
|
+
* import { s } from "@valon-technologies/gestalt";
|
|
183
|
+
*
|
|
184
|
+
* const input = s.object({
|
|
185
|
+
* name: s.string(),
|
|
186
|
+
* excited: s.optional(s.boolean()),
|
|
187
|
+
* });
|
|
188
|
+
* ```
|
|
189
|
+
*/
|
|
150
190
|
export function object<T extends Record<string, unknown>>(
|
|
151
191
|
fields: { [K in keyof T]: Schema<T[K]> },
|
|
152
192
|
options?: SchemaOptions<T>,
|
|
@@ -176,6 +216,9 @@ export function object<T extends Record<string, unknown>>(
|
|
|
176
216
|
};
|
|
177
217
|
}
|
|
178
218
|
|
|
219
|
+
/**
|
|
220
|
+
* Marks another schema as optional while preserving its metadata.
|
|
221
|
+
*/
|
|
179
222
|
export function optional<T>(schema: Schema<T>): Schema<T | undefined> {
|
|
180
223
|
const wrapped: Schema<T | undefined> = {
|
|
181
224
|
catalogType: schema.catalogType,
|
|
@@ -201,6 +244,9 @@ export function optional<T>(schema: Schema<T>): Schema<T | undefined> {
|
|
|
201
244
|
};
|
|
202
245
|
}
|
|
203
246
|
|
|
247
|
+
/**
|
|
248
|
+
* Namespace-style schema builder helpers.
|
|
249
|
+
*/
|
|
204
250
|
export const s = {
|
|
205
251
|
string,
|
|
206
252
|
integer,
|
package/src/secrets.ts
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
import { RuntimeProvider, type RuntimeProviderOptions } from "./provider.ts";
|
|
2
2
|
import type { MaybePromise } from "./api.ts";
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Runtime hooks required to implement a Gestalt secrets provider.
|
|
6
|
+
*/
|
|
4
7
|
export interface SecretsProviderOptions extends RuntimeProviderOptions {
|
|
5
8
|
getSecret: (name: string) => MaybePromise<string>;
|
|
6
9
|
}
|
|
7
10
|
|
|
11
|
+
/**
|
|
12
|
+
* Secrets provider implementation consumed by the Gestalt runtime.
|
|
13
|
+
*/
|
|
8
14
|
export class SecretsProvider extends RuntimeProvider {
|
|
9
15
|
readonly kind = "secrets" as const;
|
|
10
16
|
|
|
@@ -20,10 +26,16 @@ export class SecretsProvider extends RuntimeProvider {
|
|
|
20
26
|
}
|
|
21
27
|
}
|
|
22
28
|
|
|
29
|
+
/**
|
|
30
|
+
* Creates a secrets provider from a simple `getSecret` implementation.
|
|
31
|
+
*/
|
|
23
32
|
export function defineSecretsProvider(options: SecretsProviderOptions): SecretsProvider {
|
|
24
33
|
return new SecretsProvider(options);
|
|
25
34
|
}
|
|
26
35
|
|
|
36
|
+
/**
|
|
37
|
+
* Runtime type guard for secrets providers loaded from user modules.
|
|
38
|
+
*/
|
|
27
39
|
export function isSecretsProvider(value: unknown): value is SecretsProvider {
|
|
28
40
|
return (
|
|
29
41
|
value instanceof SecretsProvider ||
|