@barekey/cli 0.1.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/LICENSE +28 -0
- package/README.md +36 -0
- package/dist/auth-provider.d.ts +6 -0
- package/dist/auth-provider.js +58 -0
- package/dist/command-utils.d.ts +23 -0
- package/dist/command-utils.js +78 -0
- package/dist/commands/auth.d.ts +2 -0
- package/dist/commands/auth.js +186 -0
- package/dist/commands/env.d.ts +2 -0
- package/dist/commands/env.js +295 -0
- package/dist/commands/typegen.d.ts +2 -0
- package/dist/commands/typegen.js +25 -0
- package/dist/constants.d.ts +4 -0
- package/dist/constants.js +4 -0
- package/dist/credentials-store.d.ts +7 -0
- package/dist/credentials-store.js +199 -0
- package/dist/http.d.ts +22 -0
- package/dist/http.js +66 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +17 -0
- package/dist/runtime-config.d.ts +10 -0
- package/dist/runtime-config.js +49 -0
- package/dist/typegen.d.ts +20 -0
- package/dist/typegen.js +14 -0
- package/dist/types.d.ts +13 -0
- package/dist/types.js +1 -0
- package/package.json +37 -0
- package/src/auth-provider.ts +86 -0
- package/src/command-utils.ts +118 -0
- package/src/commands/auth.ts +247 -0
- package/src/commands/env.ts +496 -0
- package/src/commands/typegen.ts +38 -0
- package/src/constants.ts +4 -0
- package/src/credentials-store.ts +243 -0
- package/src/http.ts +86 -0
- package/src/index.ts +21 -0
- package/src/runtime-config.ts +66 -0
- package/src/types.ts +14 -0
- package/tsconfig.json +13 -0
|
@@ -0,0 +1,496 @@
|
|
|
1
|
+
import { writeFile } from "node:fs/promises";
|
|
2
|
+
|
|
3
|
+
import { cancel, confirm, isCancel } from "@clack/prompts";
|
|
4
|
+
import { BarekeyClient } from "@barekey/sdk";
|
|
5
|
+
import { Command } from "commander";
|
|
6
|
+
import pc from "picocolors";
|
|
7
|
+
|
|
8
|
+
import { createCliAuthProvider } from "../auth-provider.js";
|
|
9
|
+
import {
|
|
10
|
+
addTargetOptions,
|
|
11
|
+
dotenvEscape,
|
|
12
|
+
parseChance,
|
|
13
|
+
requireLocalSession,
|
|
14
|
+
resolveTarget,
|
|
15
|
+
toJsonOutput,
|
|
16
|
+
type EnvTargetOptions,
|
|
17
|
+
} from "../command-utils.js";
|
|
18
|
+
import { postJson } from "../http.js";
|
|
19
|
+
|
|
20
|
+
function createEnvClient(input: {
|
|
21
|
+
organization: string | undefined;
|
|
22
|
+
project: string;
|
|
23
|
+
environment: string;
|
|
24
|
+
}): BarekeyClient {
|
|
25
|
+
const organization = input.organization?.trim();
|
|
26
|
+
if (!organization) {
|
|
27
|
+
throw new Error("Organization slug is required.");
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return new BarekeyClient({
|
|
31
|
+
organization,
|
|
32
|
+
project: input.project,
|
|
33
|
+
environment: input.environment,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
async function runEnvGet(
|
|
38
|
+
name: string,
|
|
39
|
+
options: EnvTargetOptions & {
|
|
40
|
+
seed?: string;
|
|
41
|
+
key?: string;
|
|
42
|
+
json?: boolean;
|
|
43
|
+
},
|
|
44
|
+
): Promise<void> {
|
|
45
|
+
const local = await requireLocalSession();
|
|
46
|
+
const target = await resolveTarget(options, local);
|
|
47
|
+
const client = createEnvClient({
|
|
48
|
+
organization: target.orgSlug ?? local.credentials.orgSlug,
|
|
49
|
+
project: target.projectSlug,
|
|
50
|
+
environment: target.stageSlug,
|
|
51
|
+
});
|
|
52
|
+
const value = await client.get(name, {
|
|
53
|
+
seed: options.seed,
|
|
54
|
+
key: options.key,
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
if (options.json) {
|
|
58
|
+
toJsonOutput(true, {
|
|
59
|
+
name,
|
|
60
|
+
value,
|
|
61
|
+
});
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
console.log(String(value));
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
async function runEnvGetMany(
|
|
69
|
+
options: EnvTargetOptions & {
|
|
70
|
+
names: string;
|
|
71
|
+
seed?: string;
|
|
72
|
+
key?: string;
|
|
73
|
+
json?: boolean;
|
|
74
|
+
},
|
|
75
|
+
): Promise<void> {
|
|
76
|
+
const local = await requireLocalSession();
|
|
77
|
+
const target = await resolveTarget(options, local);
|
|
78
|
+
const client = createEnvClient({
|
|
79
|
+
organization: target.orgSlug ?? local.credentials.orgSlug,
|
|
80
|
+
project: target.projectSlug,
|
|
81
|
+
environment: target.stageSlug,
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
const names = options.names
|
|
85
|
+
.split(",")
|
|
86
|
+
.map((value) => value.trim())
|
|
87
|
+
.filter((value) => value.length > 0);
|
|
88
|
+
|
|
89
|
+
const resolved = await Promise.all(
|
|
90
|
+
names.map(async (resolvedName) => ({
|
|
91
|
+
name: resolvedName,
|
|
92
|
+
value: await client.get(resolvedName, {
|
|
93
|
+
seed: options.seed,
|
|
94
|
+
key: options.key,
|
|
95
|
+
}),
|
|
96
|
+
})),
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
if (options.json) {
|
|
100
|
+
toJsonOutput(true, resolved);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
for (const value of resolved.sort((left, right) => left.name.localeCompare(right.name))) {
|
|
105
|
+
if (value) {
|
|
106
|
+
console.log(`${value.name}=${String(value.value)}`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
async function runEnvList(options: EnvTargetOptions & { json?: boolean }): Promise<void> {
|
|
112
|
+
const local = await requireLocalSession();
|
|
113
|
+
const target = await resolveTarget(options, local);
|
|
114
|
+
const authProvider = createCliAuthProvider();
|
|
115
|
+
const accessToken = await authProvider.getAccessToken();
|
|
116
|
+
|
|
117
|
+
const response = await postJson<{
|
|
118
|
+
variables: Array<{
|
|
119
|
+
name: string;
|
|
120
|
+
kind: "secret" | "ab_roll" | "rollout";
|
|
121
|
+
declaredType: "string" | "boolean" | "int64" | "float" | "date" | "json";
|
|
122
|
+
createdAtMs: number;
|
|
123
|
+
updatedAtMs: number;
|
|
124
|
+
chance: number | null;
|
|
125
|
+
rolloutFunction: "linear" | null;
|
|
126
|
+
rolloutMilestones: Array<{ at: string; percentage: number }> | null;
|
|
127
|
+
}>;
|
|
128
|
+
}>({
|
|
129
|
+
baseUrl: local.baseUrl,
|
|
130
|
+
path: "/v1/env/list",
|
|
131
|
+
accessToken,
|
|
132
|
+
payload: {
|
|
133
|
+
orgSlug: target.orgSlug,
|
|
134
|
+
projectSlug: target.projectSlug,
|
|
135
|
+
stageSlug: target.stageSlug,
|
|
136
|
+
},
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
if (options.json) {
|
|
140
|
+
toJsonOutput(true, response.variables);
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if (response.variables.length === 0) {
|
|
145
|
+
console.log("No variables found.");
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
for (const row of response.variables) {
|
|
150
|
+
const chanceSuffix = row.kind === "ab_roll" ? ` chance=${row.chance ?? 0}` : "";
|
|
151
|
+
const rolloutSuffix =
|
|
152
|
+
row.kind === "rollout"
|
|
153
|
+
? ` ${pc.dim(
|
|
154
|
+
`${row.rolloutFunction ?? "linear"}(${row.rolloutMilestones?.length ?? 0} milestones)`,
|
|
155
|
+
)}`
|
|
156
|
+
: "";
|
|
157
|
+
console.log(
|
|
158
|
+
`${row.name} ${pc.dim(row.kind)} ${pc.dim(row.declaredType)}${chanceSuffix}${rolloutSuffix}`,
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
async function runEnvWrite(
|
|
164
|
+
operation: "create_only" | "upsert",
|
|
165
|
+
name: string,
|
|
166
|
+
value: string,
|
|
167
|
+
options: EnvTargetOptions & {
|
|
168
|
+
ab?: string;
|
|
169
|
+
chance?: string;
|
|
170
|
+
type?: "string" | "boolean" | "int64" | "float" | "date" | "json";
|
|
171
|
+
json?: boolean;
|
|
172
|
+
},
|
|
173
|
+
): Promise<void> {
|
|
174
|
+
const local = await requireLocalSession();
|
|
175
|
+
const target = await resolveTarget(options, local);
|
|
176
|
+
const authProvider = createCliAuthProvider();
|
|
177
|
+
const accessToken = await authProvider.getAccessToken();
|
|
178
|
+
|
|
179
|
+
const entry =
|
|
180
|
+
options.ab !== undefined
|
|
181
|
+
? {
|
|
182
|
+
name,
|
|
183
|
+
kind: "ab_roll" as const,
|
|
184
|
+
declaredType: options.type ?? "string",
|
|
185
|
+
valueA: value,
|
|
186
|
+
valueB: options.ab,
|
|
187
|
+
chance: parseChance(options.chance),
|
|
188
|
+
}
|
|
189
|
+
: {
|
|
190
|
+
name,
|
|
191
|
+
kind: "secret" as const,
|
|
192
|
+
declaredType: options.type ?? "string",
|
|
193
|
+
value,
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
const result = await postJson<{
|
|
197
|
+
createdCount: number;
|
|
198
|
+
updatedCount: number;
|
|
199
|
+
deletedCount: number;
|
|
200
|
+
}>({
|
|
201
|
+
baseUrl: local.baseUrl,
|
|
202
|
+
path: "/v1/env/write",
|
|
203
|
+
accessToken,
|
|
204
|
+
payload: {
|
|
205
|
+
orgSlug: target.orgSlug,
|
|
206
|
+
projectSlug: target.projectSlug,
|
|
207
|
+
stageSlug: target.stageSlug,
|
|
208
|
+
mode: operation,
|
|
209
|
+
entries: [entry],
|
|
210
|
+
deletes: [],
|
|
211
|
+
},
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
if (options.json) {
|
|
215
|
+
toJsonOutput(true, result);
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
console.log(
|
|
220
|
+
`Created: ${result.createdCount}, Updated: ${result.updatedCount}, Deleted: ${result.deletedCount}`,
|
|
221
|
+
);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
async function runEnvDelete(
|
|
225
|
+
name: string,
|
|
226
|
+
options: EnvTargetOptions & {
|
|
227
|
+
yes?: boolean;
|
|
228
|
+
ignoreMissing?: boolean;
|
|
229
|
+
json?: boolean;
|
|
230
|
+
},
|
|
231
|
+
): Promise<void> {
|
|
232
|
+
const local = await requireLocalSession();
|
|
233
|
+
const target = await resolveTarget(options, local);
|
|
234
|
+
const authProvider = createCliAuthProvider();
|
|
235
|
+
const accessToken = await authProvider.getAccessToken();
|
|
236
|
+
|
|
237
|
+
if (!options.ignoreMissing) {
|
|
238
|
+
const listed = await postJson<{
|
|
239
|
+
variables: Array<{
|
|
240
|
+
name: string;
|
|
241
|
+
}>;
|
|
242
|
+
}>({
|
|
243
|
+
baseUrl: local.baseUrl,
|
|
244
|
+
path: "/v1/env/list",
|
|
245
|
+
accessToken,
|
|
246
|
+
payload: {
|
|
247
|
+
orgSlug: target.orgSlug,
|
|
248
|
+
projectSlug: target.projectSlug,
|
|
249
|
+
stageSlug: target.stageSlug,
|
|
250
|
+
},
|
|
251
|
+
});
|
|
252
|
+
const exists = listed.variables.some((row) => row.name === name);
|
|
253
|
+
if (!exists) {
|
|
254
|
+
throw new Error(`Variable ${name} was not found in this stage.`);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
if (!options.yes) {
|
|
259
|
+
if (!process.stdout.isTTY) {
|
|
260
|
+
throw new Error("Deletion requires --yes in non-interactive mode.");
|
|
261
|
+
}
|
|
262
|
+
const confirmed = await confirm({
|
|
263
|
+
message: `Delete variable ${name}?`,
|
|
264
|
+
initialValue: false,
|
|
265
|
+
});
|
|
266
|
+
if (isCancel(confirmed)) {
|
|
267
|
+
cancel("Delete canceled.");
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
if (!confirmed) {
|
|
271
|
+
throw new Error("Delete canceled.");
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
const result = await postJson<{
|
|
276
|
+
createdCount: number;
|
|
277
|
+
updatedCount: number;
|
|
278
|
+
deletedCount: number;
|
|
279
|
+
}>({
|
|
280
|
+
baseUrl: local.baseUrl,
|
|
281
|
+
path: "/v1/env/write",
|
|
282
|
+
accessToken,
|
|
283
|
+
payload: {
|
|
284
|
+
orgSlug: target.orgSlug,
|
|
285
|
+
projectSlug: target.projectSlug,
|
|
286
|
+
stageSlug: target.stageSlug,
|
|
287
|
+
mode: "upsert",
|
|
288
|
+
entries: [],
|
|
289
|
+
deletes: [name],
|
|
290
|
+
},
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
if (options.json) {
|
|
294
|
+
toJsonOutput(true, result);
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
console.log(`Deleted: ${result.deletedCount}`);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
async function runEnvPull(
|
|
302
|
+
options: EnvTargetOptions & {
|
|
303
|
+
format?: "dotenv" | "json";
|
|
304
|
+
out?: string;
|
|
305
|
+
seed?: string;
|
|
306
|
+
key?: string;
|
|
307
|
+
redact?: boolean;
|
|
308
|
+
},
|
|
309
|
+
): Promise<void> {
|
|
310
|
+
const local = await requireLocalSession();
|
|
311
|
+
const target = await resolveTarget(options, local);
|
|
312
|
+
const authProvider = createCliAuthProvider();
|
|
313
|
+
const accessToken = await authProvider.getAccessToken();
|
|
314
|
+
|
|
315
|
+
const response = await postJson<{
|
|
316
|
+
values: Array<{
|
|
317
|
+
name: string;
|
|
318
|
+
kind: "secret" | "ab_roll";
|
|
319
|
+
declaredType: "string" | "boolean" | "int64" | "float" | "date" | "json";
|
|
320
|
+
value: string;
|
|
321
|
+
}>;
|
|
322
|
+
byName: Record<string, string>;
|
|
323
|
+
}>({
|
|
324
|
+
baseUrl: local.baseUrl,
|
|
325
|
+
path: "/v1/env/pull",
|
|
326
|
+
accessToken,
|
|
327
|
+
payload: {
|
|
328
|
+
orgSlug: target.orgSlug,
|
|
329
|
+
projectSlug: target.projectSlug,
|
|
330
|
+
stageSlug: target.stageSlug,
|
|
331
|
+
seed: options.seed,
|
|
332
|
+
key: options.key,
|
|
333
|
+
},
|
|
334
|
+
});
|
|
335
|
+
|
|
336
|
+
const format = options.format ?? "dotenv";
|
|
337
|
+
const sortedKeys = Object.keys(response.byName).sort((left, right) => left.localeCompare(right));
|
|
338
|
+
const output =
|
|
339
|
+
format === "json"
|
|
340
|
+
? `${JSON.stringify(response.byName, null, 2)}\n`
|
|
341
|
+
: `${sortedKeys.map((keyName) => `${keyName}=${dotenvEscape(response.byName[keyName] ?? "")}`).join("\n")}\n`;
|
|
342
|
+
|
|
343
|
+
if (options.out) {
|
|
344
|
+
await writeFile(options.out, output, "utf8");
|
|
345
|
+
console.log(`Wrote ${options.out}`);
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
if (options.redact && !process.stdout.isTTY) {
|
|
350
|
+
console.log(`Pulled ${response.values.length} variables.`);
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
process.stdout.write(output);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
export function registerEnvCommands(program: Command): void {
|
|
358
|
+
const env = program.command("env").description("Environment variable operations");
|
|
359
|
+
|
|
360
|
+
addTargetOptions(
|
|
361
|
+
env
|
|
362
|
+
.command("get")
|
|
363
|
+
.description("Evaluate one variable")
|
|
364
|
+
.argument("<name>", "Variable name")
|
|
365
|
+
.option("--seed <value>", "Deterministic seed")
|
|
366
|
+
.option("--key <value>", "Deterministic key")
|
|
367
|
+
.option("--json", "Machine-readable output", false),
|
|
368
|
+
).action(
|
|
369
|
+
async (
|
|
370
|
+
name: string,
|
|
371
|
+
options: EnvTargetOptions & { seed?: string; key?: string; json?: boolean },
|
|
372
|
+
) => {
|
|
373
|
+
await runEnvGet(name, options);
|
|
374
|
+
},
|
|
375
|
+
);
|
|
376
|
+
|
|
377
|
+
addTargetOptions(
|
|
378
|
+
env
|
|
379
|
+
.command("get-many")
|
|
380
|
+
.description("Evaluate a batch of variables")
|
|
381
|
+
.requiredOption("--names <csv>", "Comma-separated variable names")
|
|
382
|
+
.option("--seed <value>", "Deterministic seed")
|
|
383
|
+
.option("--key <value>", "Deterministic key")
|
|
384
|
+
.option("--json", "Machine-readable output", false),
|
|
385
|
+
).action(
|
|
386
|
+
async (
|
|
387
|
+
options: EnvTargetOptions & {
|
|
388
|
+
names: string;
|
|
389
|
+
seed?: string;
|
|
390
|
+
key?: string;
|
|
391
|
+
json?: boolean;
|
|
392
|
+
},
|
|
393
|
+
) => {
|
|
394
|
+
await runEnvGetMany(options);
|
|
395
|
+
},
|
|
396
|
+
);
|
|
397
|
+
|
|
398
|
+
addTargetOptions(
|
|
399
|
+
env
|
|
400
|
+
.command("list")
|
|
401
|
+
.description("List variables for a project stage")
|
|
402
|
+
.option("--json", "Machine-readable output", false),
|
|
403
|
+
).action(async (options: EnvTargetOptions & { json?: boolean }) => {
|
|
404
|
+
await runEnvList(options);
|
|
405
|
+
});
|
|
406
|
+
|
|
407
|
+
addTargetOptions(
|
|
408
|
+
env
|
|
409
|
+
.command("new")
|
|
410
|
+
.description("Create one variable")
|
|
411
|
+
.argument("<name>", "Variable name")
|
|
412
|
+
.argument("<value>", "Variable value")
|
|
413
|
+
.option("--ab <value-b>", "Second value for ab_roll")
|
|
414
|
+
.option("--chance <number>", "A-branch probability between 0 and 1")
|
|
415
|
+
.option("--type <type>", "Declared value type", "string")
|
|
416
|
+
.option("--json", "Machine-readable output", false),
|
|
417
|
+
).action(
|
|
418
|
+
async (
|
|
419
|
+
name: string,
|
|
420
|
+
value: string,
|
|
421
|
+
options: EnvTargetOptions & {
|
|
422
|
+
ab?: string;
|
|
423
|
+
chance?: string;
|
|
424
|
+
type?: "string" | "boolean" | "int64" | "float" | "date" | "json";
|
|
425
|
+
json?: boolean;
|
|
426
|
+
},
|
|
427
|
+
) => {
|
|
428
|
+
await runEnvWrite("create_only", name, value, options);
|
|
429
|
+
},
|
|
430
|
+
);
|
|
431
|
+
|
|
432
|
+
addTargetOptions(
|
|
433
|
+
env
|
|
434
|
+
.command("set")
|
|
435
|
+
.description("Upsert one variable")
|
|
436
|
+
.argument("<name>", "Variable name")
|
|
437
|
+
.argument("<value>", "Variable value")
|
|
438
|
+
.option("--ab <value-b>", "Second value for ab_roll")
|
|
439
|
+
.option("--chance <number>", "A-branch probability between 0 and 1")
|
|
440
|
+
.option("--type <type>", "Declared value type", "string")
|
|
441
|
+
.option("--json", "Machine-readable output", false),
|
|
442
|
+
).action(
|
|
443
|
+
async (
|
|
444
|
+
name: string,
|
|
445
|
+
value: string,
|
|
446
|
+
options: EnvTargetOptions & {
|
|
447
|
+
ab?: string;
|
|
448
|
+
chance?: string;
|
|
449
|
+
type?: "string" | "boolean" | "int64" | "float" | "date" | "json";
|
|
450
|
+
json?: boolean;
|
|
451
|
+
},
|
|
452
|
+
) => {
|
|
453
|
+
await runEnvWrite("upsert", name, value, options);
|
|
454
|
+
},
|
|
455
|
+
);
|
|
456
|
+
|
|
457
|
+
addTargetOptions(
|
|
458
|
+
env
|
|
459
|
+
.command("delete")
|
|
460
|
+
.description("Delete one variable")
|
|
461
|
+
.argument("<name>", "Variable name")
|
|
462
|
+
.option("--yes", "Skip confirmation", false)
|
|
463
|
+
.option("--ignore-missing", "Do not fail when variable is missing", false)
|
|
464
|
+
.option("--json", "Machine-readable output", false),
|
|
465
|
+
).action(
|
|
466
|
+
async (
|
|
467
|
+
name: string,
|
|
468
|
+
options: EnvTargetOptions & { yes?: boolean; ignoreMissing?: boolean; json?: boolean },
|
|
469
|
+
) => {
|
|
470
|
+
await runEnvDelete(name, options);
|
|
471
|
+
},
|
|
472
|
+
);
|
|
473
|
+
|
|
474
|
+
addTargetOptions(
|
|
475
|
+
env
|
|
476
|
+
.command("pull")
|
|
477
|
+
.description("Pull resolved variables for a project stage")
|
|
478
|
+
.option("--format <type>", "Output format: dotenv|json", "dotenv")
|
|
479
|
+
.option("--out <path>", "Output file path")
|
|
480
|
+
.option("--seed <value>", "Deterministic seed")
|
|
481
|
+
.option("--key <value>", "Deterministic key")
|
|
482
|
+
.option("--redact", "Print only summary in non-file mode", false),
|
|
483
|
+
).action(
|
|
484
|
+
async (
|
|
485
|
+
options: EnvTargetOptions & {
|
|
486
|
+
format?: "dotenv" | "json";
|
|
487
|
+
out?: string;
|
|
488
|
+
seed?: string;
|
|
489
|
+
key?: string;
|
|
490
|
+
redact?: boolean;
|
|
491
|
+
},
|
|
492
|
+
) => {
|
|
493
|
+
await runEnvPull(options);
|
|
494
|
+
},
|
|
495
|
+
);
|
|
496
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { BarekeyClient } from "@barekey/sdk";
|
|
2
|
+
import { Command } from "commander";
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
addTargetOptions,
|
|
6
|
+
requireLocalSession,
|
|
7
|
+
resolveTarget,
|
|
8
|
+
type EnvTargetOptions,
|
|
9
|
+
} from "../command-utils.js";
|
|
10
|
+
|
|
11
|
+
async function runTypegen(options: EnvTargetOptions): Promise<void> {
|
|
12
|
+
const local = await requireLocalSession();
|
|
13
|
+
const target = await resolveTarget(options, local);
|
|
14
|
+
const organization = target.orgSlug ?? local.credentials.orgSlug;
|
|
15
|
+
if (!organization || organization.trim().length === 0) {
|
|
16
|
+
throw new Error("Organization slug is required.");
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const client = new BarekeyClient({
|
|
20
|
+
organization,
|
|
21
|
+
project: target.projectSlug,
|
|
22
|
+
environment: target.stageSlug,
|
|
23
|
+
typegen: false,
|
|
24
|
+
});
|
|
25
|
+
const result = await client.typegen();
|
|
26
|
+
|
|
27
|
+
console.log(`${result.written ? "Updated" : "Unchanged"} ${result.path}`);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function registerTypegenCommand(program: Command): void {
|
|
31
|
+
addTargetOptions(
|
|
32
|
+
program
|
|
33
|
+
.command("typegen")
|
|
34
|
+
.description("Generate Barekey SDK types in the installed @barekey/sdk module"),
|
|
35
|
+
).action(async (options: EnvTargetOptions) => {
|
|
36
|
+
await runTypegen(options);
|
|
37
|
+
});
|
|
38
|
+
}
|
package/src/constants.ts
ADDED