@barekey/sdk 0.2.0 → 0.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/client.d.ts +9 -3
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +159 -39
- package/dist/handle.d.ts +15 -1
- package/dist/handle.d.ts.map +1 -1
- package/dist/handle.js +59 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/internal/evaluate.d.ts.map +1 -1
- package/dist/internal/evaluate.js +3 -0
- package/dist/internal/singleton.d.ts +5 -0
- package/dist/internal/singleton.d.ts.map +1 -0
- package/dist/internal/singleton.js +135 -0
- package/dist/key-types.typecheck.d.ts.map +1 -1
- package/dist/key-types.typecheck.js +2 -0
- package/dist/public-client.d.ts +8 -3
- package/dist/public-client.d.ts.map +1 -1
- package/dist/public-client.js +106 -9
- package/dist/public-types.d.ts +3 -1
- package/dist/public-types.d.ts.map +1 -1
- package/dist/public.d.ts +3 -3
- package/dist/public.d.ts.map +1 -1
- package/dist/public.js +1 -1
- package/dist/server.d.ts +2 -2
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +1 -1
- package/dist/types.d.ts +18 -0
- package/dist/types.d.ts.map +1 -1
- package/index.d.ts +2 -0
- package/package.json +1 -1
- package/src/client.ts +231 -48
- package/src/handle.ts +90 -2
- package/src/index.ts +11 -1
- package/src/internal/evaluate.ts +3 -0
- package/src/internal/singleton.ts +183 -0
- package/src/key-types.typecheck.ts +14 -2
- package/src/public-client.ts +159 -16
- package/src/public-types.ts +10 -0
- package/src/public.ts +8 -1
- package/src/server.ts +8 -1
- package/src/types.ts +36 -0
package/src/client.ts
CHANGED
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
NetworkError,
|
|
5
5
|
VariableNotFoundError,
|
|
6
6
|
} from "./errors.js";
|
|
7
|
-
import { BarekeyEnvHandle } from "./handle.js";
|
|
7
|
+
import { BarekeyEnvBatchHandle, BarekeyEnvHandle } from "./handle.js";
|
|
8
8
|
import {
|
|
9
9
|
evaluateDefinition,
|
|
10
10
|
inferSelectedArmFromDecision,
|
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
import { getJson, postJson } from "./internal/http.js";
|
|
15
15
|
import { validateRequirements } from "./internal/requirements.js";
|
|
16
16
|
import { resolveRuntimeContext, type BarekeyRuntimeContext } from "./internal/runtime.js";
|
|
17
|
+
import { createBarekeyClientSingletonKey } from "./internal/singleton.js";
|
|
17
18
|
import { MemoryCache } from "./internal/cache.js";
|
|
18
19
|
import { DEFAULT_TYPEGEN_TTL_MS, resolveTtlMilliseconds } from "./internal/ttl.js";
|
|
19
20
|
import {
|
|
@@ -25,11 +26,11 @@ import {
|
|
|
25
26
|
import type {
|
|
26
27
|
BarekeyClientOptions,
|
|
27
28
|
BarekeyEvaluatedValue,
|
|
28
|
-
|
|
29
|
+
BarekeyGeneratedValueForKey,
|
|
30
|
+
BarekeyGeneratedValuesForKeys,
|
|
29
31
|
BarekeyGetOptions,
|
|
30
32
|
BarekeyJsonConfig,
|
|
31
33
|
BarekeyKey,
|
|
32
|
-
BarekeyKnownKey,
|
|
33
34
|
BarekeyTypegenResult,
|
|
34
35
|
BarekeyVariableDefinition,
|
|
35
36
|
} from "./types.js";
|
|
@@ -42,10 +43,15 @@ type EvaluateResponse = {
|
|
|
42
43
|
name: string;
|
|
43
44
|
kind: BarekeyEvaluatedValue["kind"];
|
|
44
45
|
declaredType: BarekeyEvaluatedValue["declaredType"];
|
|
46
|
+
visibility: BarekeyEvaluatedValue["visibility"];
|
|
45
47
|
value: string;
|
|
46
48
|
decision?: BarekeyEvaluatedValue["decision"];
|
|
47
49
|
};
|
|
48
50
|
|
|
51
|
+
type EvaluateBatchResponse = {
|
|
52
|
+
values: Array<EvaluateResponse>;
|
|
53
|
+
};
|
|
54
|
+
|
|
49
55
|
type SharedTypegenWatcher = {
|
|
50
56
|
intervalMs: number;
|
|
51
57
|
inFlight: Promise<void> | null;
|
|
@@ -54,6 +60,7 @@ type SharedTypegenWatcher = {
|
|
|
54
60
|
};
|
|
55
61
|
|
|
56
62
|
const sharedTypegenWatchers = new Map<string, SharedTypegenWatcher>();
|
|
63
|
+
const sharedClients = new Map<string, BarekeyClient>();
|
|
57
64
|
|
|
58
65
|
function createDefaultFetch(): typeof globalThis.fetch {
|
|
59
66
|
if (typeof globalThis.fetch === "function") {
|
|
@@ -81,9 +88,39 @@ function warnAutomaticTypegenFailure(error: unknown): void {
|
|
|
81
88
|
console.warn(`[barekey] Automatic typegen refresh failed.\n${message}`);
|
|
82
89
|
}
|
|
83
90
|
|
|
91
|
+
function uniqueNames(names: readonly string[]): Array<string> {
|
|
92
|
+
return [...new Set(names)];
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function mapValuesToRequestedOrder<TValue extends { name: string }>(
|
|
96
|
+
names: readonly string[],
|
|
97
|
+
values: readonly TValue[],
|
|
98
|
+
): Array<TValue> {
|
|
99
|
+
const byName = new Map(values.map((value) => [value.name, value]));
|
|
100
|
+
return names.map((name) => {
|
|
101
|
+
const resolved = byName.get(name);
|
|
102
|
+
if (resolved === undefined) {
|
|
103
|
+
throw new VariableNotFoundError();
|
|
104
|
+
}
|
|
105
|
+
return resolved;
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function resolveEvaluatedResponse(evaluated: EvaluateResponse): BarekeyEvaluatedValue {
|
|
110
|
+
return {
|
|
111
|
+
name: evaluated.name,
|
|
112
|
+
kind: evaluated.kind,
|
|
113
|
+
declaredType: evaluated.declaredType,
|
|
114
|
+
visibility: evaluated.visibility,
|
|
115
|
+
value: evaluated.value,
|
|
116
|
+
decision: evaluated.decision,
|
|
117
|
+
selectedArm: inferSelectedArmFromDecision(evaluated.decision),
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
|
|
84
121
|
export class BarekeyClient {
|
|
85
|
-
private readonly options
|
|
86
|
-
private readonly fetchFn
|
|
122
|
+
private readonly options!: BarekeyClientOptions;
|
|
123
|
+
private readonly fetchFn!: typeof globalThis.fetch;
|
|
87
124
|
private readonly definitionCache = new MemoryCache<BarekeyVariableDefinition>();
|
|
88
125
|
private readonly evaluationCache = new MemoryCache<BarekeyEvaluatedValue>();
|
|
89
126
|
private runtimeContextPromise: Promise<BarekeyRuntimeContext> | null = null;
|
|
@@ -104,17 +141,37 @@ export class BarekeyClient {
|
|
|
104
141
|
typegen?: BarekeyClientOptions["typegen"];
|
|
105
142
|
});
|
|
106
143
|
constructor(options: BarekeyClientOptions = {}) {
|
|
144
|
+
const singletonKey = createBarekeyClientSingletonKey(options);
|
|
145
|
+
const existing = sharedClients.get(singletonKey);
|
|
146
|
+
if (existing !== undefined) {
|
|
147
|
+
return existing;
|
|
148
|
+
}
|
|
149
|
+
|
|
107
150
|
this.options = options;
|
|
108
151
|
this.fetchFn = createDefaultFetch();
|
|
152
|
+
sharedClients.set(singletonKey, this);
|
|
109
153
|
}
|
|
110
154
|
|
|
111
155
|
get<TKey extends BarekeyKey>(
|
|
112
156
|
name: TKey,
|
|
113
157
|
options?: BarekeyGetOptions,
|
|
114
|
-
): BarekeyEnvHandle<TKey
|
|
115
|
-
get
|
|
158
|
+
): BarekeyEnvHandle<BarekeyGeneratedValueForKey<TKey>>;
|
|
159
|
+
get<const TKeys extends readonly BarekeyKey[]>(
|
|
160
|
+
names: TKeys,
|
|
161
|
+
options?: BarekeyGetOptions,
|
|
162
|
+
): BarekeyEnvBatchHandle<BarekeyGeneratedValuesForKeys<TKeys>>;
|
|
163
|
+
get(
|
|
164
|
+
nameOrNames: string | readonly string[],
|
|
165
|
+
options?: BarekeyGetOptions,
|
|
166
|
+
): BarekeyEnvHandle<unknown> | BarekeyEnvBatchHandle<ReadonlyArray<unknown>> {
|
|
167
|
+
if (Array.isArray(nameOrNames)) {
|
|
168
|
+
return new BarekeyEnvBatchHandle(
|
|
169
|
+
async () => await this.resolveEvaluatedValues(nameOrNames, options),
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
|
|
116
173
|
return new BarekeyEnvHandle(
|
|
117
|
-
async () => await this.resolveEvaluatedValue(
|
|
174
|
+
async () => await this.resolveEvaluatedValue(nameOrNames as string, options),
|
|
118
175
|
);
|
|
119
176
|
}
|
|
120
177
|
|
|
@@ -282,6 +339,10 @@ export class BarekeyClient {
|
|
|
282
339
|
}
|
|
283
340
|
|
|
284
341
|
private async fetchDefinitions(names?: Array<string>): Promise<Array<BarekeyVariableDefinition>> {
|
|
342
|
+
if (names !== undefined && names.length === 0) {
|
|
343
|
+
return [];
|
|
344
|
+
}
|
|
345
|
+
|
|
285
346
|
const context = await this.getRuntimeContext();
|
|
286
347
|
const response = await postJson<DefinitionsResponse>({
|
|
287
348
|
fetchFn: this.fetchFn,
|
|
@@ -331,16 +392,42 @@ export class BarekeyClient {
|
|
|
331
392
|
await this.requirementsPromise;
|
|
332
393
|
}
|
|
333
394
|
|
|
334
|
-
private async
|
|
395
|
+
private async getStaticDefinitions(
|
|
396
|
+
names: readonly string[],
|
|
397
|
+
): Promise<Array<BarekeyVariableDefinition>> {
|
|
335
398
|
await this.ensureRequirementsValidated();
|
|
336
399
|
const context = await this.getRuntimeContext();
|
|
337
|
-
const
|
|
338
|
-
const
|
|
339
|
-
|
|
340
|
-
|
|
400
|
+
const cachedDefinitions = new Map<string, BarekeyVariableDefinition>();
|
|
401
|
+
const missingNames: Array<string> = [];
|
|
402
|
+
|
|
403
|
+
for (const name of uniqueNames(names)) {
|
|
404
|
+
const cacheKey = this.buildDefinitionCacheKey(context, name);
|
|
405
|
+
const cached = this.definitionCache.get(cacheKey);
|
|
406
|
+
if (cached !== null) {
|
|
407
|
+
cachedDefinitions.set(name, cached);
|
|
408
|
+
continue;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
missingNames.push(name);
|
|
341
412
|
}
|
|
342
413
|
|
|
343
|
-
|
|
414
|
+
if (missingNames.length > 0) {
|
|
415
|
+
for (const definition of await this.fetchDefinitions(missingNames)) {
|
|
416
|
+
cachedDefinitions.set(definition.name, definition);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
return names.map((name) => {
|
|
421
|
+
const resolved = cachedDefinitions.get(name);
|
|
422
|
+
if (resolved === undefined) {
|
|
423
|
+
throw new VariableNotFoundError();
|
|
424
|
+
}
|
|
425
|
+
return resolved;
|
|
426
|
+
});
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
private async getStaticDefinition(name: string): Promise<BarekeyVariableDefinition> {
|
|
430
|
+
const definitions = await this.getStaticDefinitions([name]);
|
|
344
431
|
const resolved = definitions[0];
|
|
345
432
|
if (resolved === undefined) {
|
|
346
433
|
throw new VariableNotFoundError();
|
|
@@ -356,61 +443,95 @@ export class BarekeyClient {
|
|
|
356
443
|
return await evaluateDefinition(definition, options);
|
|
357
444
|
}
|
|
358
445
|
|
|
359
|
-
private async
|
|
360
|
-
|
|
446
|
+
private async resolveStaticValues(
|
|
447
|
+
names: readonly string[],
|
|
361
448
|
options?: BarekeyGetOptions,
|
|
362
|
-
): Promise<BarekeyEvaluatedValue
|
|
363
|
-
await this.
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
dynamic !== undefined && dynamic !== true
|
|
369
|
-
? resolveTtlMilliseconds(dynamic.ttl, "dynamic.ttl")
|
|
370
|
-
: null;
|
|
371
|
-
if (dynamic !== true) {
|
|
372
|
-
const cached = this.evaluationCache.getRecord(cacheKey);
|
|
373
|
-
if (cached !== null && dynamicTtlMs !== null && Date.now() - cached.storedAtMs <= dynamicTtlMs) {
|
|
374
|
-
return cached.value;
|
|
375
|
-
}
|
|
376
|
-
}
|
|
449
|
+
): Promise<Array<BarekeyEvaluatedValue>> {
|
|
450
|
+
const definitions = await this.getStaticDefinitions(names);
|
|
451
|
+
return await Promise.all(
|
|
452
|
+
definitions.map(async (definition) => await evaluateDefinition(definition, options)),
|
|
453
|
+
);
|
|
454
|
+
}
|
|
377
455
|
|
|
378
|
-
|
|
456
|
+
private async fetchDynamicValues(
|
|
457
|
+
names: readonly string[],
|
|
458
|
+
context: BarekeyRuntimeContext,
|
|
459
|
+
options?: BarekeyGetOptions,
|
|
460
|
+
): Promise<Array<BarekeyEvaluatedValue>> {
|
|
379
461
|
try {
|
|
380
|
-
|
|
462
|
+
if (names.length === 1) {
|
|
463
|
+
const evaluated = await postJson<EvaluateResponse>({
|
|
464
|
+
fetchFn: this.fetchFn,
|
|
465
|
+
baseUrl: context.baseUrl,
|
|
466
|
+
path: "/v1/env/evaluate",
|
|
467
|
+
payload: {
|
|
468
|
+
orgSlug: context.organization,
|
|
469
|
+
projectSlug: context.project,
|
|
470
|
+
stageSlug: context.environment,
|
|
471
|
+
name: names[0],
|
|
472
|
+
seed: options?.seed,
|
|
473
|
+
key: options?.key,
|
|
474
|
+
},
|
|
475
|
+
auth: context.auth,
|
|
476
|
+
});
|
|
477
|
+
|
|
478
|
+
return [resolveEvaluatedResponse(evaluated)];
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
const evaluated = await postJson<EvaluateBatchResponse>({
|
|
381
482
|
fetchFn: this.fetchFn,
|
|
382
483
|
baseUrl: context.baseUrl,
|
|
383
|
-
path: "/v1/env/evaluate",
|
|
484
|
+
path: "/v1/env/evaluate-batch",
|
|
384
485
|
payload: {
|
|
385
486
|
orgSlug: context.organization,
|
|
386
487
|
projectSlug: context.project,
|
|
387
488
|
stageSlug: context.environment,
|
|
388
|
-
|
|
489
|
+
names,
|
|
389
490
|
seed: options?.seed,
|
|
390
491
|
key: options?.key,
|
|
391
492
|
},
|
|
392
493
|
auth: context.auth,
|
|
393
494
|
});
|
|
394
495
|
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
value: evaluated.value,
|
|
400
|
-
decision: evaluated.decision,
|
|
401
|
-
selectedArm: inferSelectedArmFromDecision(evaluated.decision),
|
|
402
|
-
};
|
|
496
|
+
return mapValuesToRequestedOrder(
|
|
497
|
+
names,
|
|
498
|
+
evaluated.values.map((value) => resolveEvaluatedResponse(value)),
|
|
499
|
+
);
|
|
403
500
|
} catch (error: unknown) {
|
|
404
501
|
if (!(error instanceof BillingUnavailableError)) {
|
|
405
502
|
throw error;
|
|
406
503
|
}
|
|
407
504
|
|
|
408
|
-
const
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
505
|
+
const definitions = await this.getStaticDefinitions(names);
|
|
506
|
+
return await Promise.all(
|
|
507
|
+
definitions.map(async (definition) => await evaluateDefinition(definition, options)),
|
|
508
|
+
);
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
private async resolveDynamicValue(
|
|
513
|
+
name: string,
|
|
514
|
+
options?: BarekeyGetOptions,
|
|
515
|
+
): Promise<BarekeyEvaluatedValue> {
|
|
516
|
+
await this.ensureRequirementsValidated();
|
|
517
|
+
const context = await this.getRuntimeContext();
|
|
518
|
+
const cacheKey = this.buildEvaluationCacheKey(context, name, options);
|
|
519
|
+
const dynamic = options?.dynamic;
|
|
520
|
+
const dynamicTtlMs =
|
|
521
|
+
dynamic !== undefined && dynamic !== true
|
|
522
|
+
? resolveTtlMilliseconds(dynamic.ttl, "dynamic.ttl")
|
|
523
|
+
: null;
|
|
524
|
+
if (dynamic !== true) {
|
|
525
|
+
const cached = this.evaluationCache.getRecord(cacheKey);
|
|
526
|
+
if (cached !== null && dynamicTtlMs !== null && Date.now() - cached.storedAtMs <= dynamicTtlMs) {
|
|
527
|
+
return cached.value;
|
|
412
528
|
}
|
|
413
|
-
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
const resolvedValues = await this.fetchDynamicValues([name], context, options);
|
|
532
|
+
const resolved = resolvedValues[0];
|
|
533
|
+
if (resolved === undefined) {
|
|
534
|
+
throw new VariableNotFoundError();
|
|
414
535
|
}
|
|
415
536
|
|
|
416
537
|
if (dynamicTtlMs !== null) {
|
|
@@ -422,6 +543,45 @@ export class BarekeyClient {
|
|
|
422
543
|
return resolved;
|
|
423
544
|
}
|
|
424
545
|
|
|
546
|
+
private async resolveDynamicValues(
|
|
547
|
+
names: readonly string[],
|
|
548
|
+
options?: BarekeyGetOptions,
|
|
549
|
+
): Promise<Array<BarekeyEvaluatedValue>> {
|
|
550
|
+
await this.ensureRequirementsValidated();
|
|
551
|
+
const context = await this.getRuntimeContext();
|
|
552
|
+
const dynamic = options?.dynamic;
|
|
553
|
+
const dynamicTtlMs =
|
|
554
|
+
dynamic !== undefined && dynamic !== true
|
|
555
|
+
? resolveTtlMilliseconds(dynamic.ttl, "dynamic.ttl")
|
|
556
|
+
: null;
|
|
557
|
+
const resolvedValues = new Map<string, BarekeyEvaluatedValue>();
|
|
558
|
+
const missingNames: Array<string> = [];
|
|
559
|
+
|
|
560
|
+
for (const name of uniqueNames(names)) {
|
|
561
|
+
const cacheKey = this.buildEvaluationCacheKey(context, name, options);
|
|
562
|
+
if (dynamic !== true) {
|
|
563
|
+
const cached = this.evaluationCache.getRecord(cacheKey);
|
|
564
|
+
if (cached !== null && dynamicTtlMs !== null && Date.now() - cached.storedAtMs <= dynamicTtlMs) {
|
|
565
|
+
resolvedValues.set(name, cached.value);
|
|
566
|
+
continue;
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
missingNames.push(name);
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
if (missingNames.length > 0) {
|
|
574
|
+
for (const resolved of await this.fetchDynamicValues(missingNames, context, options)) {
|
|
575
|
+
resolvedValues.set(resolved.name, resolved);
|
|
576
|
+
if (dynamicTtlMs !== null) {
|
|
577
|
+
this.evaluationCache.set(this.buildEvaluationCacheKey(context, resolved.name, options), resolved);
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
return mapValuesToRequestedOrder(names, [...resolvedValues.values()]);
|
|
583
|
+
}
|
|
584
|
+
|
|
425
585
|
private async resolveEvaluatedValue(
|
|
426
586
|
name: string,
|
|
427
587
|
options?: BarekeyGetOptions,
|
|
@@ -434,4 +594,27 @@ export class BarekeyClient {
|
|
|
434
594
|
}
|
|
435
595
|
return await this.resolveDynamicValue(name, options);
|
|
436
596
|
}
|
|
597
|
+
|
|
598
|
+
private async resolveEvaluatedValues(
|
|
599
|
+
names: readonly string[],
|
|
600
|
+
options?: BarekeyGetOptions,
|
|
601
|
+
): Promise<Array<BarekeyEvaluatedValue>> {
|
|
602
|
+
if (names.length === 0) {
|
|
603
|
+
return [];
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
if (uniqueNames(names).length === 1) {
|
|
607
|
+
const resolved = await this.resolveEvaluatedValue(names[0] ?? "", options);
|
|
608
|
+
return names.map(() => resolved);
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
const context = await this.getRuntimeContext();
|
|
612
|
+
this.ensureTypegenWatcher(context);
|
|
613
|
+
validateDynamicOptions(options);
|
|
614
|
+
if (options?.dynamic === undefined) {
|
|
615
|
+
return await this.resolveStaticValues(names, options);
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
return await this.resolveDynamicValues(names, options);
|
|
619
|
+
}
|
|
437
620
|
}
|
package/src/handle.ts
CHANGED
|
@@ -2,7 +2,12 @@ import {
|
|
|
2
2
|
coerceEvaluatedValue,
|
|
3
3
|
parseDeclaredValue,
|
|
4
4
|
} from "./internal/evaluate.js";
|
|
5
|
-
import type {
|
|
5
|
+
import type {
|
|
6
|
+
BarekeyCoerceTarget,
|
|
7
|
+
BarekeyEvaluatedValue,
|
|
8
|
+
BarekeyResolvedRecord,
|
|
9
|
+
BarekeyResolvedRecords,
|
|
10
|
+
} from "./types.js";
|
|
6
11
|
|
|
7
12
|
type BarekeyCoercibleEnvMarker = {
|
|
8
13
|
readonly __barekey?: {
|
|
@@ -10,10 +15,22 @@ type BarekeyCoercibleEnvMarker = {
|
|
|
10
15
|
};
|
|
11
16
|
};
|
|
12
17
|
|
|
18
|
+
function buildResolvedRecord<TValue>(
|
|
19
|
+
resolved: BarekeyEvaluatedValue,
|
|
20
|
+
value: TValue,
|
|
21
|
+
): BarekeyResolvedRecord<TValue> {
|
|
22
|
+
return {
|
|
23
|
+
...resolved,
|
|
24
|
+
rawValue: resolved.value,
|
|
25
|
+
value,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
13
29
|
export class BarekeyEnvHandle<TValue = unknown> implements PromiseLike<TValue> {
|
|
14
30
|
private readonly resolveEvaluatedValue: () => Promise<BarekeyEvaluatedValue>;
|
|
15
31
|
private readonly transform: (resolved: BarekeyEvaluatedValue) => Promise<TValue>;
|
|
16
32
|
private evaluatedValuePromise: Promise<BarekeyEvaluatedValue> | null = null;
|
|
33
|
+
private resolvedRecordPromise: Promise<BarekeyResolvedRecord<TValue>> | null = null;
|
|
17
34
|
|
|
18
35
|
constructor(
|
|
19
36
|
resolveEvaluatedValue: () => Promise<BarekeyEvaluatedValue>,
|
|
@@ -26,7 +43,7 @@ export class BarekeyEnvHandle<TValue = unknown> implements PromiseLike<TValue> {
|
|
|
26
43
|
}
|
|
27
44
|
|
|
28
45
|
private async resolveValue(): Promise<TValue> {
|
|
29
|
-
return
|
|
46
|
+
return (await this.inspect()).value;
|
|
30
47
|
}
|
|
31
48
|
|
|
32
49
|
private async getEvaluatedValue(): Promise<BarekeyEvaluatedValue> {
|
|
@@ -36,6 +53,18 @@ export class BarekeyEnvHandle<TValue = unknown> implements PromiseLike<TValue> {
|
|
|
36
53
|
return await this.evaluatedValuePromise;
|
|
37
54
|
}
|
|
38
55
|
|
|
56
|
+
async inspect(): Promise<BarekeyResolvedRecord<TValue>> {
|
|
57
|
+
if (this.resolvedRecordPromise === null) {
|
|
58
|
+
this.resolvedRecordPromise = (async () => {
|
|
59
|
+
const resolved = await this.getEvaluatedValue();
|
|
60
|
+
const value = await this.transform(resolved);
|
|
61
|
+
return buildResolvedRecord(resolved, value);
|
|
62
|
+
})();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return await this.resolvedRecordPromise;
|
|
66
|
+
}
|
|
67
|
+
|
|
39
68
|
coerce<TCoerced = unknown>(
|
|
40
69
|
this: [TValue] extends [BarekeyCoercibleEnvMarker] ? BarekeyEnvHandle<TValue> : never,
|
|
41
70
|
target: BarekeyCoerceTarget,
|
|
@@ -65,3 +94,62 @@ export class BarekeyEnvHandle<TValue = unknown> implements PromiseLike<TValue> {
|
|
|
65
94
|
return this.resolveValue().finally(onfinally ?? undefined);
|
|
66
95
|
}
|
|
67
96
|
}
|
|
97
|
+
|
|
98
|
+
export class BarekeyEnvBatchHandle<
|
|
99
|
+
TValues extends ReadonlyArray<unknown> = Array<unknown>,
|
|
100
|
+
> implements PromiseLike<TValues>
|
|
101
|
+
{
|
|
102
|
+
private readonly resolveEvaluatedValues: () => Promise<ReadonlyArray<BarekeyEvaluatedValue>>;
|
|
103
|
+
private evaluatedValuesPromise: Promise<ReadonlyArray<BarekeyEvaluatedValue>> | null = null;
|
|
104
|
+
private resolvedRecordsPromise: Promise<BarekeyResolvedRecords<TValues>> | null = null;
|
|
105
|
+
|
|
106
|
+
constructor(resolveEvaluatedValues: () => Promise<ReadonlyArray<BarekeyEvaluatedValue>>) {
|
|
107
|
+
this.resolveEvaluatedValues = resolveEvaluatedValues;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
private async getEvaluatedValues(): Promise<ReadonlyArray<BarekeyEvaluatedValue>> {
|
|
111
|
+
if (this.evaluatedValuesPromise === null) {
|
|
112
|
+
this.evaluatedValuesPromise = this.resolveEvaluatedValues();
|
|
113
|
+
}
|
|
114
|
+
return await this.evaluatedValuesPromise;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
async inspect(): Promise<BarekeyResolvedRecords<TValues>> {
|
|
118
|
+
if (this.resolvedRecordsPromise === null) {
|
|
119
|
+
this.resolvedRecordsPromise = (async () => {
|
|
120
|
+
const resolvedValues = await this.getEvaluatedValues();
|
|
121
|
+
const records = await Promise.all(
|
|
122
|
+
resolvedValues.map(async (resolved) => {
|
|
123
|
+
const value = parseDeclaredValue(resolved.value, resolved.declaredType);
|
|
124
|
+
return buildResolvedRecord(resolved, value);
|
|
125
|
+
}),
|
|
126
|
+
);
|
|
127
|
+
return records as BarekeyResolvedRecords<TValues>;
|
|
128
|
+
})();
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return await this.resolvedRecordsPromise;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
private async resolveValues(): Promise<TValues> {
|
|
135
|
+
const resolvedRecords = await this.inspect();
|
|
136
|
+
return resolvedRecords.map((resolved) => resolved.value) as unknown as TValues;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
then<TResult1 = TValues, TResult2 = never>(
|
|
140
|
+
onfulfilled?: ((value: TValues) => TResult1 | PromiseLike<TResult1>) | null,
|
|
141
|
+
onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,
|
|
142
|
+
): Promise<TResult1 | TResult2> {
|
|
143
|
+
return this.resolveValues().then(onfulfilled ?? undefined, onrejected ?? undefined);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
catch<TResult = never>(
|
|
147
|
+
onrejected?: ((reason: unknown) => TResult | PromiseLike<TResult>) | null,
|
|
148
|
+
): Promise<TValues | TResult> {
|
|
149
|
+
return this.resolveValues().catch(onrejected ?? undefined);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
finally(onfinally?: (() => void) | null): Promise<TValues> {
|
|
153
|
+
return this.resolveValues().finally(onfinally ?? undefined);
|
|
154
|
+
}
|
|
155
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { BarekeyClient } from "./client.js";
|
|
2
2
|
export { PublicBarekeyClient } from "./public-client.js";
|
|
3
|
-
export { BarekeyEnvHandle } from "./handle.js";
|
|
3
|
+
export { BarekeyEnvBatchHandle, BarekeyEnvHandle } from "./handle.js";
|
|
4
4
|
export {
|
|
5
5
|
BarekeyError,
|
|
6
6
|
BillingUnavailableError,
|
|
@@ -44,12 +44,17 @@ export type {
|
|
|
44
44
|
BarekeyCoerceTarget,
|
|
45
45
|
BarekeyDeclaredType,
|
|
46
46
|
BarekeyErrorCode,
|
|
47
|
+
BarekeyEvaluatedValue,
|
|
47
48
|
BarekeyGeneratedTypeMap,
|
|
49
|
+
BarekeyGeneratedValueForKey,
|
|
50
|
+
BarekeyGeneratedValuesForKeys,
|
|
48
51
|
BarekeyGetOptions,
|
|
49
52
|
BarekeyJsonConfig,
|
|
50
53
|
BarekeyKey,
|
|
51
54
|
BarekeyLiteralString,
|
|
52
55
|
BarekeyKnownKey,
|
|
56
|
+
BarekeyResolvedRecord,
|
|
57
|
+
BarekeyResolvedRecords,
|
|
53
58
|
BarekeyResolvedKind,
|
|
54
59
|
BarekeyRolloutMilestone,
|
|
55
60
|
BarekeyStandardSchemaV1,
|
|
@@ -57,14 +62,19 @@ export type {
|
|
|
57
62
|
BarekeyTemporalInstantLike,
|
|
58
63
|
BarekeyTtlInput,
|
|
59
64
|
BarekeyTypegenResult,
|
|
65
|
+
BarekeyValueForGeneratedMap,
|
|
66
|
+
BarekeyValuesForGeneratedMap,
|
|
60
67
|
Env,
|
|
61
68
|
Linear,
|
|
62
69
|
Secret,
|
|
70
|
+
BarekeyVisibility,
|
|
63
71
|
} from "./types.js";
|
|
64
72
|
|
|
65
73
|
export type {
|
|
66
74
|
BarekeyPublicGeneratedTypeMap,
|
|
67
75
|
BarekeyPublicKey,
|
|
68
76
|
BarekeyPublicKnownKey,
|
|
77
|
+
BarekeyPublicValueForKey,
|
|
78
|
+
BarekeyPublicValuesForKeys,
|
|
69
79
|
PublicBarekeyClientOptions,
|
|
70
80
|
} from "./public-types.js";
|
package/src/internal/evaluate.ts
CHANGED
|
@@ -196,6 +196,7 @@ export async function evaluateDefinition(
|
|
|
196
196
|
name: definition.name,
|
|
197
197
|
kind: definition.kind,
|
|
198
198
|
declaredType: definition.declaredType,
|
|
199
|
+
visibility: definition.visibility,
|
|
199
200
|
value: definition.value,
|
|
200
201
|
};
|
|
201
202
|
}
|
|
@@ -213,6 +214,7 @@ export async function evaluateDefinition(
|
|
|
213
214
|
name: definition.name,
|
|
214
215
|
kind: definition.kind,
|
|
215
216
|
declaredType: definition.declaredType,
|
|
217
|
+
visibility: definition.visibility,
|
|
216
218
|
value: selectedArm === "A" ? definition.valueA : definition.valueB,
|
|
217
219
|
selectedArm,
|
|
218
220
|
decision: {
|
|
@@ -235,6 +237,7 @@ export async function evaluateDefinition(
|
|
|
235
237
|
name: definition.name,
|
|
236
238
|
kind: definition.kind,
|
|
237
239
|
declaredType: definition.declaredType,
|
|
240
|
+
visibility: definition.visibility,
|
|
238
241
|
value: selectedArm === "A" ? definition.valueA : definition.valueB,
|
|
239
242
|
selectedArm,
|
|
240
243
|
decision: {
|