@barekey/sdk 0.2.1 → 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/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
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import type { PublicBarekeyClientOptions } from "../public-types.js";
|
|
2
|
+
import type {
|
|
3
|
+
BarekeyClientOptions,
|
|
4
|
+
BarekeyJsonConfig,
|
|
5
|
+
BarekeyStandardSchemaV1,
|
|
6
|
+
BarekeyTtlInput,
|
|
7
|
+
} from "../types.js";
|
|
8
|
+
import { normalizeBaseUrl } from "./http.js";
|
|
9
|
+
|
|
10
|
+
const DEFAULT_BAREKEY_API_URL = "https://api.barekey.dev";
|
|
11
|
+
|
|
12
|
+
const referenceIds = new WeakMap<object, number>();
|
|
13
|
+
let nextReferenceId = 1;
|
|
14
|
+
|
|
15
|
+
function readConfigString(value: unknown): string | null {
|
|
16
|
+
if (typeof value !== "string") {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return value.trim();
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function getReferenceId(value: object): number {
|
|
24
|
+
const existing = referenceIds.get(value);
|
|
25
|
+
if (existing !== undefined) {
|
|
26
|
+
return existing;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const nextId = nextReferenceId;
|
|
30
|
+
nextReferenceId += 1;
|
|
31
|
+
referenceIds.set(value, nextId);
|
|
32
|
+
return nextId;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function safeCurrentWorkingDirectory(): string {
|
|
36
|
+
if (typeof process === "undefined" || typeof process.cwd !== "function") {
|
|
37
|
+
return "";
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return process.cwd();
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function normalizeJsonScope(
|
|
44
|
+
value: BarekeyJsonConfig | undefined,
|
|
45
|
+
): { organization: string | null; project: string | null; environment: string | null } | null {
|
|
46
|
+
if (value === undefined) {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return {
|
|
51
|
+
organization: readConfigString(value.organization ?? value.org),
|
|
52
|
+
project: readConfigString(value.project),
|
|
53
|
+
environment: readConfigString(value.environment ?? value.stage),
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function normalizeScopeKey(
|
|
58
|
+
options:
|
|
59
|
+
| BarekeyClientOptions
|
|
60
|
+
| PublicBarekeyClientOptions,
|
|
61
|
+
): { organization: string | null; project: string | null; environment: string | null } | {
|
|
62
|
+
cwd: string;
|
|
63
|
+
} {
|
|
64
|
+
const jsonScope = normalizeJsonScope("json" in options ? options.json : undefined);
|
|
65
|
+
if (jsonScope !== null) {
|
|
66
|
+
return jsonScope;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const organization = "organization" in options ? readConfigString(options.organization) : null;
|
|
70
|
+
const project = "project" in options ? readConfigString(options.project) : null;
|
|
71
|
+
const environment = "environment" in options ? readConfigString(options.environment) : null;
|
|
72
|
+
if (organization !== null || project !== null || environment !== null) {
|
|
73
|
+
return {
|
|
74
|
+
organization,
|
|
75
|
+
project,
|
|
76
|
+
environment,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return {
|
|
81
|
+
cwd: safeCurrentWorkingDirectory(),
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function normalizeTtlKey(value: BarekeyTtlInput | undefined): unknown {
|
|
86
|
+
if (value === undefined) {
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (typeof value === "number") {
|
|
91
|
+
return {
|
|
92
|
+
kind: "milliseconds",
|
|
93
|
+
value,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (value instanceof Date) {
|
|
98
|
+
return {
|
|
99
|
+
kind: "date",
|
|
100
|
+
value: value.getTime(),
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (typeof value === "object" && value !== null && "epochMilliseconds" in value) {
|
|
105
|
+
const epochMilliseconds = (value as { epochMilliseconds?: unknown }).epochMilliseconds;
|
|
106
|
+
if (typeof epochMilliseconds === "number") {
|
|
107
|
+
return {
|
|
108
|
+
kind: "temporal",
|
|
109
|
+
value: epochMilliseconds,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return {
|
|
115
|
+
kind: "reference",
|
|
116
|
+
value: getReferenceId(value as object),
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function normalizeRequirementsKey(value: BarekeyStandardSchemaV1 | undefined): unknown {
|
|
121
|
+
if (value === undefined) {
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return {
|
|
126
|
+
kind: "reference",
|
|
127
|
+
value: getReferenceId(value as object),
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function stableStringify(value: unknown): string {
|
|
132
|
+
if (value === null) {
|
|
133
|
+
return "null";
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
137
|
+
return JSON.stringify(value);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (typeof value === "undefined") {
|
|
141
|
+
return '"__undefined__"';
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if (Array.isArray(value)) {
|
|
145
|
+
return `[${value.map((entry) => stableStringify(entry)).join(",")}]`;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (typeof value === "object") {
|
|
149
|
+
const entries = Object.entries(value as Record<string, unknown>).sort(([left], [right]) =>
|
|
150
|
+
left.localeCompare(right),
|
|
151
|
+
);
|
|
152
|
+
return `{${entries
|
|
153
|
+
.map(([key, entryValue]) => `${JSON.stringify(key)}:${stableStringify(entryValue)}`)
|
|
154
|
+
.join(",")}}`;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return JSON.stringify(String(value));
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export function createBarekeyClientSingletonKey(options: BarekeyClientOptions): string {
|
|
161
|
+
return stableStringify({
|
|
162
|
+
kind: "server",
|
|
163
|
+
scope: normalizeScopeKey(options),
|
|
164
|
+
requirements: normalizeRequirementsKey(options.requirements),
|
|
165
|
+
typegen:
|
|
166
|
+
options.typegen === false
|
|
167
|
+
? false
|
|
168
|
+
: {
|
|
169
|
+
ttl: normalizeTtlKey(options.typegen?.ttl),
|
|
170
|
+
},
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export function createPublicBarekeyClientSingletonKey(
|
|
175
|
+
options: PublicBarekeyClientOptions,
|
|
176
|
+
): string {
|
|
177
|
+
return stableStringify({
|
|
178
|
+
kind: "public",
|
|
179
|
+
scope: normalizeScopeKey(options),
|
|
180
|
+
requirements: normalizeRequirementsKey(options.requirements),
|
|
181
|
+
baseUrl: normalizeBaseUrl(options.baseUrl?.trim() || DEFAULT_BAREKEY_API_URL),
|
|
182
|
+
});
|
|
183
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { BarekeyClient } from "./client.js";
|
|
2
|
-
import type { BarekeyEnvHandle } from "./handle.js";
|
|
2
|
+
import type { BarekeyEnvBatchHandle, BarekeyEnvHandle } from "./handle.js";
|
|
3
3
|
import type { PublicBarekeyClient } from "./public-client.js";
|
|
4
4
|
import type { Env, Secret } from "./types.js";
|
|
5
5
|
import type {
|
|
@@ -34,15 +34,21 @@ type IsEqual<TLeft, TRight> = (<TValue>() => TValue extends TLeft ? 1 : 2) exten
|
|
|
34
34
|
? true
|
|
35
35
|
: false;
|
|
36
36
|
|
|
37
|
-
type UnwrapHandle<TValue> = TValue extends BarekeyEnvHandle<infer TResolved>
|
|
37
|
+
type UnwrapHandle<TValue> = TValue extends BarekeyEnvHandle<infer TResolved>
|
|
38
|
+
? TResolved
|
|
39
|
+
: TValue extends BarekeyEnvBatchHandle<infer TResolved>
|
|
40
|
+
? TResolved
|
|
41
|
+
: never;
|
|
38
42
|
|
|
39
43
|
declare const client: BarekeyClient;
|
|
40
44
|
declare const publicClient: PublicBarekeyClient;
|
|
41
45
|
|
|
42
46
|
const privateKnownHandle = client.get("PRIVATE_TOKEN");
|
|
43
47
|
const privateUnknownHandle = client.get("SOME_RUNTIME_KEY");
|
|
48
|
+
const privateTupleHandle = client.get(["PRIVATE_TOKEN", "SOME_RUNTIME_KEY"] as const);
|
|
44
49
|
const publicKnownHandle = publicClient.get("PUBLIC_THEME");
|
|
45
50
|
const publicUnknownHandle = publicClient.get("SOME_RUNTIME_KEY");
|
|
51
|
+
const publicTupleHandle = publicClient.get(["PUBLIC_THEME", "SOME_RUNTIME_KEY"] as const);
|
|
46
52
|
|
|
47
53
|
type _barekeyKnownKeyStillExact = Assert<IsEqual<BarekeyKnownKey, "PRIVATE_TOKEN">>;
|
|
48
54
|
type _barekeyPublicKnownKeyStillExact = Assert<IsEqual<BarekeyPublicKnownKey, "PUBLIC_THEME">>;
|
|
@@ -64,5 +70,11 @@ type _publicKnownHandleKeepsGeneratedValue = Assert<
|
|
|
64
70
|
type _publicUnknownHandleFallsBackToUnknown = Assert<
|
|
65
71
|
IsEqual<UnwrapHandle<typeof publicUnknownHandle>, unknown>
|
|
66
72
|
>;
|
|
73
|
+
type _privateTupleHandleMapsKnownAndUnknownKeys = Assert<
|
|
74
|
+
IsEqual<UnwrapHandle<typeof privateTupleHandle>, readonly [BarekeyGeneratedTypeMap["PRIVATE_TOKEN"], unknown]>
|
|
75
|
+
>;
|
|
76
|
+
type _publicTupleHandleMapsKnownAndUnknownKeys = Assert<
|
|
77
|
+
IsEqual<UnwrapHandle<typeof publicTupleHandle>, readonly [BarekeyPublicGeneratedTypeMap["PUBLIC_THEME"], unknown]>
|
|
78
|
+
>;
|
|
67
79
|
|
|
68
80
|
export {};
|
package/src/public-client.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { VariableNotFoundError } from "./errors.js";
|
|
2
|
-
import { BarekeyEnvHandle } from "./handle.js";
|
|
2
|
+
import { BarekeyEnvBatchHandle, BarekeyEnvHandle } from "./handle.js";
|
|
3
3
|
import {
|
|
4
4
|
evaluateDefinition,
|
|
5
5
|
parseDeclaredValue,
|
|
@@ -12,11 +12,12 @@ import {
|
|
|
12
12
|
resolvePublicRuntimeContext,
|
|
13
13
|
type BarekeyPublicRuntimeContext,
|
|
14
14
|
} from "./internal/public-runtime.js";
|
|
15
|
+
import { createPublicBarekeyClientSingletonKey } from "./internal/singleton.js";
|
|
15
16
|
import { resolveTtlMilliseconds } from "./internal/ttl.js";
|
|
16
17
|
import type {
|
|
17
|
-
|
|
18
|
+
BarekeyPublicValueForKey,
|
|
19
|
+
BarekeyPublicValuesForKeys,
|
|
18
20
|
BarekeyPublicKey,
|
|
19
|
-
BarekeyPublicKnownKey,
|
|
20
21
|
PublicBarekeyClientOptions,
|
|
21
22
|
} from "./public-types.js";
|
|
22
23
|
import type {
|
|
@@ -30,6 +31,8 @@ type DefinitionsResponse = {
|
|
|
30
31
|
definitions: Array<BarekeyVariableDefinition>;
|
|
31
32
|
};
|
|
32
33
|
|
|
34
|
+
const sharedClients = new Map<string, PublicBarekeyClient>();
|
|
35
|
+
|
|
33
36
|
function createDefaultFetch(): typeof globalThis.fetch {
|
|
34
37
|
if (typeof globalThis.fetch === "function") {
|
|
35
38
|
return globalThis.fetch.bind(globalThis);
|
|
@@ -40,9 +43,27 @@ function createDefaultFetch(): typeof globalThis.fetch {
|
|
|
40
43
|
}) as typeof globalThis.fetch;
|
|
41
44
|
}
|
|
42
45
|
|
|
46
|
+
function uniqueNames(names: readonly string[]): Array<string> {
|
|
47
|
+
return [...new Set(names)];
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function mapValuesToRequestedOrder<TValue extends { name: string }>(
|
|
51
|
+
names: readonly string[],
|
|
52
|
+
values: readonly TValue[],
|
|
53
|
+
): Array<TValue> {
|
|
54
|
+
const byName = new Map(values.map((value) => [value.name, value]));
|
|
55
|
+
return names.map((name) => {
|
|
56
|
+
const resolved = byName.get(name);
|
|
57
|
+
if (resolved === undefined) {
|
|
58
|
+
throw new VariableNotFoundError();
|
|
59
|
+
}
|
|
60
|
+
return resolved;
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
|
|
43
64
|
export class PublicBarekeyClient {
|
|
44
|
-
private readonly options
|
|
45
|
-
private readonly fetchFn
|
|
65
|
+
private readonly options!: PublicBarekeyClientOptions;
|
|
66
|
+
private readonly fetchFn!: typeof globalThis.fetch;
|
|
46
67
|
private readonly definitionCache = new MemoryCache<BarekeyVariableDefinition>();
|
|
47
68
|
private readonly evaluationCache = new MemoryCache<BarekeyEvaluatedValue>();
|
|
48
69
|
private runtimeContextPromise: Promise<BarekeyPublicRuntimeContext> | null = null;
|
|
@@ -62,19 +83,37 @@ export class PublicBarekeyClient {
|
|
|
62
83
|
baseUrl?: string;
|
|
63
84
|
});
|
|
64
85
|
constructor(options: PublicBarekeyClientOptions = {}) {
|
|
86
|
+
const singletonKey = createPublicBarekeyClientSingletonKey(options);
|
|
87
|
+
const existing = sharedClients.get(singletonKey);
|
|
88
|
+
if (existing !== undefined) {
|
|
89
|
+
return existing;
|
|
90
|
+
}
|
|
91
|
+
|
|
65
92
|
this.options = options;
|
|
66
93
|
this.fetchFn = createDefaultFetch();
|
|
94
|
+
sharedClients.set(singletonKey, this);
|
|
67
95
|
}
|
|
68
96
|
|
|
69
97
|
get<TKey extends BarekeyPublicKey>(
|
|
70
98
|
name: TKey,
|
|
71
99
|
options?: BarekeyGetOptions,
|
|
72
|
-
): BarekeyEnvHandle<
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
100
|
+
): BarekeyEnvHandle<BarekeyPublicValueForKey<TKey>>;
|
|
101
|
+
get<const TKeys extends readonly BarekeyPublicKey[]>(
|
|
102
|
+
names: TKeys,
|
|
103
|
+
options?: BarekeyGetOptions,
|
|
104
|
+
): BarekeyEnvBatchHandle<BarekeyPublicValuesForKeys<TKeys>>;
|
|
105
|
+
get(
|
|
106
|
+
nameOrNames: string | readonly string[],
|
|
107
|
+
options?: BarekeyGetOptions,
|
|
108
|
+
): BarekeyEnvHandle<unknown> | BarekeyEnvBatchHandle<ReadonlyArray<unknown>> {
|
|
109
|
+
if (Array.isArray(nameOrNames)) {
|
|
110
|
+
return new BarekeyEnvBatchHandle(
|
|
111
|
+
async () => await this.resolveEvaluatedValues(nameOrNames, options),
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
|
|
76
115
|
return new BarekeyEnvHandle(
|
|
77
|
-
async () => await this.resolveEvaluatedValue(
|
|
116
|
+
async () => await this.resolveEvaluatedValue(nameOrNames as string, options),
|
|
78
117
|
);
|
|
79
118
|
}
|
|
80
119
|
|
|
@@ -111,6 +150,10 @@ export class PublicBarekeyClient {
|
|
|
111
150
|
}
|
|
112
151
|
|
|
113
152
|
private async fetchDefinitions(names?: Array<string>): Promise<Array<BarekeyVariableDefinition>> {
|
|
153
|
+
if (names !== undefined && names.length === 0) {
|
|
154
|
+
return [];
|
|
155
|
+
}
|
|
156
|
+
|
|
114
157
|
const context = await this.getRuntimeContext();
|
|
115
158
|
const response = await postJson<DefinitionsResponse>({
|
|
116
159
|
fetchFn: this.fetchFn,
|
|
@@ -159,16 +202,42 @@ export class PublicBarekeyClient {
|
|
|
159
202
|
await this.requirementsPromise;
|
|
160
203
|
}
|
|
161
204
|
|
|
162
|
-
private async
|
|
205
|
+
private async getStaticDefinitions(
|
|
206
|
+
names: readonly string[],
|
|
207
|
+
): Promise<Array<BarekeyVariableDefinition>> {
|
|
163
208
|
await this.ensureRequirementsValidated();
|
|
164
209
|
const context = await this.getRuntimeContext();
|
|
165
|
-
const
|
|
166
|
-
const
|
|
167
|
-
|
|
168
|
-
|
|
210
|
+
const cachedDefinitions = new Map<string, BarekeyVariableDefinition>();
|
|
211
|
+
const missingNames: Array<string> = [];
|
|
212
|
+
|
|
213
|
+
for (const name of uniqueNames(names)) {
|
|
214
|
+
const cacheKey = this.buildDefinitionCacheKey(context, name);
|
|
215
|
+
const cached = this.definitionCache.get(cacheKey);
|
|
216
|
+
if (cached !== null) {
|
|
217
|
+
cachedDefinitions.set(name, cached);
|
|
218
|
+
continue;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
missingNames.push(name);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
if (missingNames.length > 0) {
|
|
225
|
+
for (const definition of await this.fetchDefinitions(missingNames)) {
|
|
226
|
+
cachedDefinitions.set(definition.name, definition);
|
|
227
|
+
}
|
|
169
228
|
}
|
|
170
229
|
|
|
171
|
-
|
|
230
|
+
return names.map((name) => {
|
|
231
|
+
const resolved = cachedDefinitions.get(name);
|
|
232
|
+
if (resolved === undefined) {
|
|
233
|
+
throw new VariableNotFoundError();
|
|
234
|
+
}
|
|
235
|
+
return resolved;
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
private async getStaticDefinition(name: string): Promise<BarekeyVariableDefinition> {
|
|
240
|
+
const definitions = await this.getStaticDefinitions([name]);
|
|
172
241
|
const resolved = definitions[0];
|
|
173
242
|
if (resolved === undefined) {
|
|
174
243
|
throw new VariableNotFoundError();
|
|
@@ -184,6 +253,16 @@ export class PublicBarekeyClient {
|
|
|
184
253
|
return await evaluateDefinition(definition, options);
|
|
185
254
|
}
|
|
186
255
|
|
|
256
|
+
private async resolveStaticValues(
|
|
257
|
+
names: readonly string[],
|
|
258
|
+
options?: BarekeyGetOptions,
|
|
259
|
+
): Promise<Array<BarekeyEvaluatedValue>> {
|
|
260
|
+
const definitions = await this.getStaticDefinitions(names);
|
|
261
|
+
return await Promise.all(
|
|
262
|
+
definitions.map(async (definition) => await evaluateDefinition(definition, options)),
|
|
263
|
+
);
|
|
264
|
+
}
|
|
265
|
+
|
|
187
266
|
private async resolveDynamicValue(
|
|
188
267
|
name: string,
|
|
189
268
|
options?: BarekeyGetOptions,
|
|
@@ -218,6 +297,49 @@ export class PublicBarekeyClient {
|
|
|
218
297
|
return resolved;
|
|
219
298
|
}
|
|
220
299
|
|
|
300
|
+
private async resolveDynamicValues(
|
|
301
|
+
names: readonly string[],
|
|
302
|
+
options?: BarekeyGetOptions,
|
|
303
|
+
): Promise<Array<BarekeyEvaluatedValue>> {
|
|
304
|
+
await this.ensureRequirementsValidated();
|
|
305
|
+
const context = await this.getRuntimeContext();
|
|
306
|
+
const dynamic = options?.dynamic;
|
|
307
|
+
const dynamicTtlMs =
|
|
308
|
+
dynamic !== undefined && dynamic !== true
|
|
309
|
+
? resolveTtlMilliseconds(dynamic.ttl, "dynamic.ttl")
|
|
310
|
+
: null;
|
|
311
|
+
const resolvedValues = new Map<string, BarekeyEvaluatedValue>();
|
|
312
|
+
const missingNames: Array<string> = [];
|
|
313
|
+
|
|
314
|
+
for (const name of uniqueNames(names)) {
|
|
315
|
+
const cacheKey = this.buildEvaluationCacheKey(context, name, options);
|
|
316
|
+
if (dynamic !== true) {
|
|
317
|
+
const cached = this.evaluationCache.getRecord(cacheKey);
|
|
318
|
+
if (cached !== null && dynamicTtlMs !== null && Date.now() - cached.storedAtMs <= dynamicTtlMs) {
|
|
319
|
+
resolvedValues.set(name, cached.value);
|
|
320
|
+
continue;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
missingNames.push(name);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
if (missingNames.length > 0) {
|
|
328
|
+
const freshDefinitions = await this.getStaticDefinitions(missingNames);
|
|
329
|
+
const freshValues = await Promise.all(
|
|
330
|
+
freshDefinitions.map(async (definition) => await evaluateDefinition(definition, options)),
|
|
331
|
+
);
|
|
332
|
+
for (const resolved of freshValues) {
|
|
333
|
+
resolvedValues.set(resolved.name, resolved);
|
|
334
|
+
if (dynamicTtlMs !== null) {
|
|
335
|
+
this.evaluationCache.set(this.buildEvaluationCacheKey(context, resolved.name, options), resolved);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
return mapValuesToRequestedOrder(names, [...resolvedValues.values()]);
|
|
341
|
+
}
|
|
342
|
+
|
|
221
343
|
private async resolveEvaluatedValue(
|
|
222
344
|
name: string,
|
|
223
345
|
options?: BarekeyGetOptions,
|
|
@@ -228,4 +350,25 @@ export class PublicBarekeyClient {
|
|
|
228
350
|
}
|
|
229
351
|
return await this.resolveDynamicValue(name, options);
|
|
230
352
|
}
|
|
353
|
+
|
|
354
|
+
private async resolveEvaluatedValues(
|
|
355
|
+
names: readonly string[],
|
|
356
|
+
options?: BarekeyGetOptions,
|
|
357
|
+
): Promise<Array<BarekeyEvaluatedValue>> {
|
|
358
|
+
if (names.length === 0) {
|
|
359
|
+
return [];
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
if (uniqueNames(names).length === 1) {
|
|
363
|
+
const resolved = await this.resolveEvaluatedValue(names[0] ?? "", options);
|
|
364
|
+
return names.map(() => resolved);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
validateDynamicOptions(options);
|
|
368
|
+
if (options?.dynamic === undefined) {
|
|
369
|
+
return await this.resolveStaticValues(names, options);
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
return await this.resolveDynamicValues(names, options);
|
|
373
|
+
}
|
|
231
374
|
}
|
package/src/public-types.ts
CHANGED
|
@@ -29,6 +29,8 @@ import type {
|
|
|
29
29
|
BarekeyJsonConfig,
|
|
30
30
|
BarekeyLiteralString,
|
|
31
31
|
BarekeyStandardSchemaV1,
|
|
32
|
+
BarekeyValueForGeneratedMap,
|
|
33
|
+
BarekeyValuesForGeneratedMap,
|
|
32
34
|
} from "./types.js";
|
|
33
35
|
|
|
34
36
|
export interface BarekeyPublicGeneratedTypeMap {}
|
|
@@ -37,6 +39,14 @@ export type BarekeyPublicKnownKey = Extract<keyof BarekeyPublicGeneratedTypeMap,
|
|
|
37
39
|
|
|
38
40
|
export type BarekeyPublicKey = BarekeyPublicKnownKey | BarekeyLiteralString;
|
|
39
41
|
|
|
42
|
+
export type BarekeyPublicValueForKey<TKey extends string> = BarekeyValueForGeneratedMap<
|
|
43
|
+
BarekeyPublicGeneratedTypeMap,
|
|
44
|
+
TKey
|
|
45
|
+
>;
|
|
46
|
+
|
|
47
|
+
export type BarekeyPublicValuesForKeys<TKeys extends readonly string[]> =
|
|
48
|
+
BarekeyValuesForGeneratedMap<BarekeyPublicGeneratedTypeMap, TKeys>;
|
|
49
|
+
|
|
40
50
|
type BarekeyPublicBaseClientOptions = {
|
|
41
51
|
requirements?: BarekeyStandardSchemaV1;
|
|
42
52
|
baseUrl?: string;
|
package/src/public.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { PublicBarekeyClient } from "./public-client.js";
|
|
2
|
-
export { BarekeyEnvHandle } from "./handle.js";
|
|
2
|
+
export { BarekeyEnvBatchHandle, BarekeyEnvHandle } from "./handle.js";
|
|
3
3
|
export {
|
|
4
4
|
BarekeyError,
|
|
5
5
|
BillingUnavailableError,
|
|
@@ -47,6 +47,8 @@ export type {
|
|
|
47
47
|
BarekeyGetOptions,
|
|
48
48
|
BarekeyJsonConfig,
|
|
49
49
|
BarekeyLiteralString,
|
|
50
|
+
BarekeyResolvedRecord,
|
|
51
|
+
BarekeyResolvedRecords,
|
|
50
52
|
BarekeyResolvedKind,
|
|
51
53
|
BarekeyRolloutFunction,
|
|
52
54
|
BarekeyRolloutMatchedRule,
|
|
@@ -55,7 +57,10 @@ export type {
|
|
|
55
57
|
BarekeyTemporalInstant,
|
|
56
58
|
BarekeyTemporalInstantLike,
|
|
57
59
|
BarekeyTtlInput,
|
|
60
|
+
BarekeyValueForGeneratedMap,
|
|
61
|
+
BarekeyValuesForGeneratedMap,
|
|
58
62
|
BarekeyVariableDefinition,
|
|
63
|
+
BarekeyVisibility,
|
|
59
64
|
EaseInOut,
|
|
60
65
|
Env,
|
|
61
66
|
Linear,
|
|
@@ -67,5 +72,7 @@ export type {
|
|
|
67
72
|
BarekeyPublicGeneratedTypeMap,
|
|
68
73
|
BarekeyPublicKey,
|
|
69
74
|
BarekeyPublicKnownKey,
|
|
75
|
+
BarekeyPublicValueForKey,
|
|
76
|
+
BarekeyPublicValuesForKeys,
|
|
70
77
|
PublicBarekeyClientOptions,
|
|
71
78
|
} from "./public-types.js";
|
package/src/server.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { BarekeyClient } from "./client.js";
|
|
2
|
-
export { BarekeyEnvHandle } from "./handle.js";
|
|
2
|
+
export { BarekeyEnvBatchHandle, BarekeyEnvHandle } from "./handle.js";
|
|
3
3
|
export {
|
|
4
4
|
BarekeyError,
|
|
5
5
|
BillingUnavailableError,
|
|
@@ -44,11 +44,15 @@ export type {
|
|
|
44
44
|
BarekeyDeclaredType,
|
|
45
45
|
BarekeyErrorCode,
|
|
46
46
|
BarekeyGeneratedTypeMap,
|
|
47
|
+
BarekeyGeneratedValueForKey,
|
|
48
|
+
BarekeyGeneratedValuesForKeys,
|
|
47
49
|
BarekeyGetOptions,
|
|
48
50
|
BarekeyJsonConfig,
|
|
49
51
|
BarekeyKey,
|
|
50
52
|
BarekeyLiteralString,
|
|
51
53
|
BarekeyKnownKey,
|
|
54
|
+
BarekeyResolvedRecord,
|
|
55
|
+
BarekeyResolvedRecords,
|
|
52
56
|
BarekeyResolvedKind,
|
|
53
57
|
BarekeyRolloutMilestone,
|
|
54
58
|
BarekeyStandardSchemaV1,
|
|
@@ -56,6 +60,9 @@ export type {
|
|
|
56
60
|
BarekeyTemporalInstantLike,
|
|
57
61
|
BarekeyTtlInput,
|
|
58
62
|
BarekeyTypegenResult,
|
|
63
|
+
BarekeyValueForGeneratedMap,
|
|
64
|
+
BarekeyValuesForGeneratedMap,
|
|
65
|
+
BarekeyVisibility,
|
|
59
66
|
Env,
|
|
60
67
|
Linear,
|
|
61
68
|
Secret,
|
package/src/types.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export type BarekeyResolvedKind = "secret" | "ab_roll" | "rollout";
|
|
2
|
+
export type BarekeyVisibility = "private" | "public";
|
|
2
3
|
|
|
3
4
|
export type BarekeyDeclaredType = "string" | "boolean" | "int64" | "float" | "date" | "json";
|
|
4
5
|
|
|
@@ -63,6 +64,28 @@ export type BarekeyLiteralString = string & {};
|
|
|
63
64
|
|
|
64
65
|
export type BarekeyKey = BarekeyKnownKey | BarekeyLiteralString;
|
|
65
66
|
|
|
67
|
+
export type BarekeyValueForGeneratedMap<
|
|
68
|
+
TMap extends object,
|
|
69
|
+
TKey extends string,
|
|
70
|
+
> = TKey extends Extract<keyof TMap, string> ? TMap[TKey] : unknown;
|
|
71
|
+
|
|
72
|
+
export type BarekeyValuesForGeneratedMap<
|
|
73
|
+
TMap extends object,
|
|
74
|
+
TKeys extends readonly string[],
|
|
75
|
+
> = {
|
|
76
|
+
[TIndex in keyof TKeys]: TKeys[TIndex] extends string
|
|
77
|
+
? BarekeyValueForGeneratedMap<TMap, TKeys[TIndex]>
|
|
78
|
+
: never;
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
export type BarekeyGeneratedValueForKey<TKey extends string> = BarekeyValueForGeneratedMap<
|
|
82
|
+
BarekeyGeneratedTypeMap,
|
|
83
|
+
TKey
|
|
84
|
+
>;
|
|
85
|
+
|
|
86
|
+
export type BarekeyGeneratedValuesForKeys<TKeys extends readonly string[]> =
|
|
87
|
+
BarekeyValuesForGeneratedMap<BarekeyGeneratedTypeMap, TKeys>;
|
|
88
|
+
|
|
66
89
|
export type BarekeyRolloutMilestone = {
|
|
67
90
|
at: string;
|
|
68
91
|
percentage: number;
|
|
@@ -87,22 +110,34 @@ export type BarekeyEvaluatedValue = {
|
|
|
87
110
|
name: string;
|
|
88
111
|
kind: BarekeyResolvedKind;
|
|
89
112
|
declaredType: BarekeyDeclaredType;
|
|
113
|
+
visibility: BarekeyVisibility;
|
|
90
114
|
value: string;
|
|
91
115
|
decision?: BarekeyDecision;
|
|
92
116
|
selectedArm?: "A" | "B";
|
|
93
117
|
};
|
|
94
118
|
|
|
119
|
+
export type BarekeyResolvedRecord<TValue = unknown> = Omit<BarekeyEvaluatedValue, "value"> & {
|
|
120
|
+
value: TValue;
|
|
121
|
+
rawValue: string;
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
export type BarekeyResolvedRecords<TValues extends ReadonlyArray<unknown>> = {
|
|
125
|
+
[TIndex in keyof TValues]: BarekeyResolvedRecord<TValues[TIndex]>;
|
|
126
|
+
};
|
|
127
|
+
|
|
95
128
|
export type BarekeyVariableDefinition =
|
|
96
129
|
| {
|
|
97
130
|
name: string;
|
|
98
131
|
kind: "secret";
|
|
99
132
|
declaredType: BarekeyDeclaredType;
|
|
133
|
+
visibility: BarekeyVisibility;
|
|
100
134
|
value: string;
|
|
101
135
|
}
|
|
102
136
|
| {
|
|
103
137
|
name: string;
|
|
104
138
|
kind: "ab_roll";
|
|
105
139
|
declaredType: BarekeyDeclaredType;
|
|
140
|
+
visibility: BarekeyVisibility;
|
|
106
141
|
valueA: string;
|
|
107
142
|
valueB: string;
|
|
108
143
|
chance: number;
|
|
@@ -111,6 +146,7 @@ export type BarekeyVariableDefinition =
|
|
|
111
146
|
name: string;
|
|
112
147
|
kind: "rollout";
|
|
113
148
|
declaredType: BarekeyDeclaredType;
|
|
149
|
+
visibility: BarekeyVisibility;
|
|
114
150
|
valueA: string;
|
|
115
151
|
valueB: string;
|
|
116
152
|
rolloutFunction: BarekeyRolloutFunction;
|