@barekey/cli 0.4.0 → 0.5.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/README.md +53 -12
- package/bun.lock +9 -3
- package/dist/auth-provider.js +7 -4
- package/dist/command-utils.js +6 -6
- package/dist/commands/audit.d.ts +2 -0
- package/dist/commands/audit.js +47 -0
- package/dist/commands/auth.js +22 -7
- package/dist/commands/billing.d.ts +2 -0
- package/dist/commands/billing.js +62 -0
- package/dist/commands/env.js +157 -125
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.js +32 -0
- package/dist/commands/org.d.ts +2 -0
- package/dist/commands/org.js +85 -0
- package/dist/commands/project.d.ts +2 -0
- package/dist/commands/project.js +99 -0
- package/dist/commands/stage.d.ts +2 -0
- package/dist/commands/stage.js +125 -0
- package/dist/commands/target-prompts.d.ts +184 -0
- package/dist/commands/target-prompts.js +312 -0
- package/dist/commands/typegen.d.ts +2 -2
- package/dist/commands/typegen.js +57 -32
- package/dist/constants.d.ts +1 -1
- package/dist/constants.js +1 -1
- package/dist/context/session-id.d.ts +11 -0
- package/dist/context/session-id.js +14 -0
- package/dist/contracts/index.d.ts +491 -0
- package/dist/contracts/index.js +307 -0
- package/dist/credentials-store.js +70 -11
- package/dist/http.d.ts +34 -0
- package/dist/http.js +56 -2
- package/dist/index.js +12 -0
- package/dist/runtime-config.js +14 -26
- package/dist/typegen/core.d.ts +45 -0
- package/dist/typegen/core.js +219 -0
- package/dist/types.d.ts +5 -3
- package/package.json +2 -2
- package/src/auth-provider.ts +8 -5
- package/src/command-utils.ts +6 -6
- package/src/commands/audit.ts +63 -0
- package/src/commands/auth.ts +32 -37
- package/src/commands/billing.ts +73 -0
- package/src/commands/env.ts +211 -218
- package/src/commands/init.ts +47 -0
- package/src/commands/org.ts +104 -0
- package/src/commands/project.ts +130 -0
- package/src/commands/stage.ts +167 -0
- package/src/commands/target-prompts.ts +357 -0
- package/src/commands/typegen.ts +71 -45
- package/src/constants.ts +1 -1
- package/src/context/session-id.ts +14 -0
- package/src/contracts/index.ts +370 -0
- package/src/credentials-store.ts +86 -12
- package/src/http.ts +78 -2
- package/src/index.ts +12 -0
- package/src/runtime-config.ts +19 -32
- package/src/typegen/core.ts +311 -0
- package/src/types.ts +5 -3
- package/test/command-utils.test.ts +47 -0
- package/test/credentials-store.test.ts +40 -0
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
import { Schema } from "effect";
|
|
2
|
+
|
|
3
|
+
export const DeclaredTypeSchema = Schema.Literal(
|
|
4
|
+
"string",
|
|
5
|
+
"boolean",
|
|
6
|
+
"int64",
|
|
7
|
+
"float",
|
|
8
|
+
"date",
|
|
9
|
+
"json",
|
|
10
|
+
);
|
|
11
|
+
export const VisibilitySchema = Schema.Literal("private", "public");
|
|
12
|
+
export const RolloutFunctionSchema = Schema.Literal("linear", "step", "ease_in_out");
|
|
13
|
+
export const RuntimeModeSchema = Schema.Literal("centralized", "standalone");
|
|
14
|
+
export const TypegenModeSchema = Schema.Literal("semantic", "minimal");
|
|
15
|
+
|
|
16
|
+
const TrimmedStringSchema = Schema.String;
|
|
17
|
+
const NonEmptyStringSchema = Schema.String.pipe(Schema.minLength(1));
|
|
18
|
+
|
|
19
|
+
export const RuntimeConfigSchema = Schema.Struct({
|
|
20
|
+
organization: Schema.optional(Schema.NullOr(TrimmedStringSchema)),
|
|
21
|
+
org: Schema.optional(Schema.NullOr(TrimmedStringSchema)),
|
|
22
|
+
project: Schema.optional(Schema.NullOr(TrimmedStringSchema)),
|
|
23
|
+
environment: Schema.optional(Schema.NullOr(TrimmedStringSchema)),
|
|
24
|
+
stage: Schema.optional(Schema.NullOr(TrimmedStringSchema)),
|
|
25
|
+
typegen: Schema.optional(Schema.NullOr(TypegenModeSchema)),
|
|
26
|
+
config: Schema.optional(
|
|
27
|
+
Schema.Struct({
|
|
28
|
+
typegen: Schema.optional(TypegenModeSchema),
|
|
29
|
+
mode: Schema.optional(RuntimeModeSchema),
|
|
30
|
+
}),
|
|
31
|
+
),
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
export const CliConfigSchema = Schema.Union(
|
|
35
|
+
Schema.Struct({
|
|
36
|
+
baseUrl: NonEmptyStringSchema,
|
|
37
|
+
activeSessionId: NonEmptyStringSchema,
|
|
38
|
+
}),
|
|
39
|
+
Schema.Struct({
|
|
40
|
+
baseUrl: NonEmptyStringSchema,
|
|
41
|
+
activeAccountId: NonEmptyStringSchema,
|
|
42
|
+
}),
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
export const CliSessionSchema = Schema.Union(
|
|
46
|
+
Schema.Struct({
|
|
47
|
+
accessToken: NonEmptyStringSchema,
|
|
48
|
+
refreshToken: NonEmptyStringSchema,
|
|
49
|
+
accessTokenExpiresAtMs: Schema.Number.pipe(Schema.finite()),
|
|
50
|
+
refreshTokenExpiresAtMs: Schema.Number.pipe(Schema.finite()),
|
|
51
|
+
clerkUserId: NonEmptyStringSchema,
|
|
52
|
+
orgId: Schema.NullOr(NonEmptyStringSchema),
|
|
53
|
+
orgSlug: Schema.NullOr(NonEmptyStringSchema),
|
|
54
|
+
lastOrgId: Schema.optional(Schema.NullOr(NonEmptyStringSchema)),
|
|
55
|
+
lastOrgSlug: Schema.optional(Schema.NullOr(NonEmptyStringSchema)),
|
|
56
|
+
}),
|
|
57
|
+
Schema.Struct({
|
|
58
|
+
accessToken: NonEmptyStringSchema,
|
|
59
|
+
refreshToken: NonEmptyStringSchema,
|
|
60
|
+
accessTokenExpiresAtMs: Schema.Number.pipe(Schema.finite()),
|
|
61
|
+
refreshTokenExpiresAtMs: Schema.Number.pipe(Schema.finite()),
|
|
62
|
+
clerkUserId: NonEmptyStringSchema,
|
|
63
|
+
orgId: NonEmptyStringSchema,
|
|
64
|
+
orgSlug: NonEmptyStringSchema,
|
|
65
|
+
}),
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
export const ErrorEnvelopeSchema = Schema.Struct({
|
|
69
|
+
error: Schema.Struct({
|
|
70
|
+
code: Schema.optional(Schema.String),
|
|
71
|
+
message: Schema.optional(Schema.String),
|
|
72
|
+
requestId: Schema.optional(Schema.NullOr(Schema.String)),
|
|
73
|
+
}),
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
export const CliSessionResponseSchema = Schema.Struct({
|
|
77
|
+
clerkUserId: Schema.String,
|
|
78
|
+
orgId: Schema.String,
|
|
79
|
+
orgSlug: Schema.String,
|
|
80
|
+
source: Schema.Literal("clerk", "cli"),
|
|
81
|
+
requestId: Schema.optional(Schema.String),
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
export const DeviceStartResponseSchema = Schema.Struct({
|
|
85
|
+
deviceCode: Schema.String,
|
|
86
|
+
userCode: Schema.String,
|
|
87
|
+
verificationUri: Schema.String,
|
|
88
|
+
intervalSec: Schema.Number.pipe(Schema.finite()),
|
|
89
|
+
expiresInSec: Schema.Number.pipe(Schema.finite()),
|
|
90
|
+
requestId: Schema.optional(Schema.String),
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
export const DevicePollPendingSchema = Schema.Struct({
|
|
94
|
+
status: Schema.Literal("pending"),
|
|
95
|
+
intervalSec: Schema.Number.pipe(Schema.finite()),
|
|
96
|
+
requestId: Schema.optional(Schema.String),
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
export const DevicePollApprovedSchema = Schema.Struct({
|
|
100
|
+
status: Schema.Literal("approved"),
|
|
101
|
+
intervalSec: Schema.Number.pipe(Schema.finite()),
|
|
102
|
+
accessToken: Schema.String,
|
|
103
|
+
refreshToken: Schema.String,
|
|
104
|
+
accessTokenExpiresAtMs: Schema.Number.pipe(Schema.finite()),
|
|
105
|
+
refreshTokenExpiresAtMs: Schema.Number.pipe(Schema.finite()),
|
|
106
|
+
orgId: Schema.String,
|
|
107
|
+
orgSlug: Schema.String,
|
|
108
|
+
clerkUserId: Schema.String,
|
|
109
|
+
requestId: Schema.optional(Schema.String),
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
export const DevicePollResponseSchema = Schema.Union(
|
|
113
|
+
DevicePollPendingSchema,
|
|
114
|
+
DevicePollApprovedSchema,
|
|
115
|
+
);
|
|
116
|
+
|
|
117
|
+
export const RefreshResponseSchema = Schema.Struct({
|
|
118
|
+
accessToken: Schema.String,
|
|
119
|
+
refreshToken: Schema.String,
|
|
120
|
+
accessTokenExpiresAtMs: Schema.Number.pipe(Schema.finite()),
|
|
121
|
+
refreshTokenExpiresAtMs: Schema.Number.pipe(Schema.finite()),
|
|
122
|
+
orgId: Schema.String,
|
|
123
|
+
orgSlug: Schema.String,
|
|
124
|
+
clerkUserId: Schema.String,
|
|
125
|
+
requestId: Schema.optional(Schema.String),
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
export const EnvDecisionSchema = Schema.Struct({
|
|
129
|
+
bucket: Schema.Number.pipe(Schema.finite()),
|
|
130
|
+
chance: Schema.Number.pipe(Schema.finite()),
|
|
131
|
+
seed: Schema.optional(Schema.String),
|
|
132
|
+
key: Schema.optional(Schema.String),
|
|
133
|
+
matchedRule: Schema.String,
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
export const EnvResolvedValueSchema = Schema.Struct({
|
|
137
|
+
name: Schema.String,
|
|
138
|
+
kind: Schema.Literal("secret", "ab_roll", "rollout"),
|
|
139
|
+
declaredType: DeclaredTypeSchema,
|
|
140
|
+
visibility: VisibilitySchema,
|
|
141
|
+
value: Schema.Unknown,
|
|
142
|
+
decision: Schema.optional(EnvDecisionSchema),
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
export const EnvEvaluateResponseSchema = Schema.Struct({
|
|
146
|
+
name: Schema.String,
|
|
147
|
+
kind: Schema.Literal("secret", "ab_roll", "rollout"),
|
|
148
|
+
declaredType: DeclaredTypeSchema,
|
|
149
|
+
visibility: VisibilitySchema,
|
|
150
|
+
value: Schema.Unknown,
|
|
151
|
+
decision: Schema.optional(EnvDecisionSchema),
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
export const EnvEvaluateBatchResponseSchema = Schema.Struct({
|
|
155
|
+
values: Schema.Array(EnvResolvedValueSchema),
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
export const RolloutMilestoneSchema = Schema.Struct({
|
|
159
|
+
at: Schema.String,
|
|
160
|
+
percentage: Schema.Number.pipe(Schema.finite()),
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
export const EnvVariableListItemSchema = Schema.Struct({
|
|
164
|
+
name: Schema.String,
|
|
165
|
+
visibility: VisibilitySchema,
|
|
166
|
+
kind: Schema.Literal("secret", "ab_roll", "rollout"),
|
|
167
|
+
declaredType: DeclaredTypeSchema,
|
|
168
|
+
createdAtMs: Schema.Number.pipe(Schema.finite()),
|
|
169
|
+
updatedAtMs: Schema.Number.pipe(Schema.finite()),
|
|
170
|
+
chance: Schema.NullOr(Schema.Number.pipe(Schema.finite())),
|
|
171
|
+
rolloutFunction: Schema.NullOr(RolloutFunctionSchema),
|
|
172
|
+
rolloutMilestones: Schema.NullOr(Schema.Array(RolloutMilestoneSchema)),
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
export const EnvListResponseSchema = Schema.Struct({
|
|
176
|
+
variables: Schema.Array(EnvVariableListItemSchema),
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
export const EnvWriteResponseSchema = Schema.Struct({
|
|
180
|
+
createdCount: Schema.Number.pipe(Schema.finite()),
|
|
181
|
+
updatedCount: Schema.Number.pipe(Schema.finite()),
|
|
182
|
+
deletedCount: Schema.Number.pipe(Schema.finite()),
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
export const EnvPullValueSchema = Schema.Struct({
|
|
186
|
+
name: Schema.String,
|
|
187
|
+
kind: Schema.Literal("secret", "ab_roll", "rollout"),
|
|
188
|
+
declaredType: DeclaredTypeSchema,
|
|
189
|
+
value: Schema.String,
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
export const EnvPullResponseSchema = Schema.Struct({
|
|
193
|
+
values: Schema.Array(EnvPullValueSchema),
|
|
194
|
+
byName: Schema.Record({ key: Schema.String, value: Schema.String }),
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
export const TypegenVariableSchema = Schema.Struct({
|
|
198
|
+
name: Schema.String,
|
|
199
|
+
visibility: VisibilitySchema,
|
|
200
|
+
kind: Schema.Literal("secret", "ab_roll", "rollout"),
|
|
201
|
+
declaredType: DeclaredTypeSchema,
|
|
202
|
+
required: Schema.Boolean,
|
|
203
|
+
updatedAtMs: Schema.Number.pipe(Schema.finite()),
|
|
204
|
+
typeScriptType: Schema.String,
|
|
205
|
+
valueATypeScriptType: Schema.NullOr(Schema.String),
|
|
206
|
+
valueBTypeScriptType: Schema.NullOr(Schema.String),
|
|
207
|
+
rolloutFunction: Schema.NullOr(RolloutFunctionSchema),
|
|
208
|
+
rolloutMilestones: Schema.NullOr(Schema.Array(RolloutMilestoneSchema)),
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
export const TypegenManifestSchema = Schema.Struct({
|
|
212
|
+
orgId: Schema.String,
|
|
213
|
+
orgSlug: Schema.String,
|
|
214
|
+
projectSlug: Schema.String,
|
|
215
|
+
stageSlug: Schema.String,
|
|
216
|
+
generatedAtMs: Schema.Number.pipe(Schema.finite()),
|
|
217
|
+
manifestVersion: Schema.String,
|
|
218
|
+
variables: Schema.Array(TypegenVariableSchema),
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
export const OrganizationSummarySchema = Schema.Struct({
|
|
222
|
+
id: Schema.String,
|
|
223
|
+
slug: Schema.String,
|
|
224
|
+
name: Schema.String,
|
|
225
|
+
role: Schema.String,
|
|
226
|
+
imageUrl: Schema.String,
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
export const OrganizationsResponseSchema = Schema.Struct({
|
|
230
|
+
organizations: Schema.Array(OrganizationSummarySchema),
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
export const ProjectSummarySchema = Schema.Struct({
|
|
234
|
+
id: Schema.String,
|
|
235
|
+
orgId: Schema.String,
|
|
236
|
+
orgSlug: Schema.String,
|
|
237
|
+
name: Schema.String,
|
|
238
|
+
slug: Schema.String,
|
|
239
|
+
slugBase: Schema.String,
|
|
240
|
+
createdByClerkUserId: Schema.String,
|
|
241
|
+
createdAtMs: Schema.Number.pipe(Schema.finite()),
|
|
242
|
+
updatedAtMs: Schema.Number.pipe(Schema.finite()),
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
export const ProjectListItemSchema = Schema.Struct({
|
|
246
|
+
id: Schema.String,
|
|
247
|
+
orgId: Schema.String,
|
|
248
|
+
orgSlug: Schema.String,
|
|
249
|
+
name: Schema.String,
|
|
250
|
+
slug: Schema.String,
|
|
251
|
+
slugBase: Schema.String,
|
|
252
|
+
createdByClerkUserId: Schema.String,
|
|
253
|
+
createdAtMs: Schema.Number.pipe(Schema.finite()),
|
|
254
|
+
updatedAtMs: Schema.Number.pipe(Schema.finite()),
|
|
255
|
+
secretCount: Schema.Number.pipe(Schema.finite()),
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
export const ProjectsListResponseSchema = Schema.Struct({
|
|
259
|
+
projects: Schema.Array(ProjectListItemSchema),
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
export const ProjectCreateResponseSchema = Schema.Struct({
|
|
263
|
+
project: ProjectSummarySchema,
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
export const ProjectDeleteResponseSchema = Schema.Struct({
|
|
267
|
+
deletedProjectId: Schema.String,
|
|
268
|
+
deletedProjectSlug: Schema.String,
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
export const StageSummarySchema = Schema.Struct({
|
|
272
|
+
id: Schema.String,
|
|
273
|
+
projectId: Schema.String,
|
|
274
|
+
orgId: Schema.String,
|
|
275
|
+
slug: Schema.String,
|
|
276
|
+
name: Schema.String,
|
|
277
|
+
isDefault: Schema.Boolean,
|
|
278
|
+
variableCount: Schema.Number.pipe(Schema.finite()),
|
|
279
|
+
createdAtMs: Schema.Number.pipe(Schema.finite()),
|
|
280
|
+
updatedAtMs: Schema.Number.pipe(Schema.finite()),
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
export const StagesListResponseSchema = Schema.Struct({
|
|
284
|
+
stages: Schema.Array(StageSummarySchema),
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
export const StageCreateResponseSchema = Schema.Struct({
|
|
288
|
+
stage: StageSummarySchema,
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
export const StageRenameResponseSchema = Schema.Struct({
|
|
292
|
+
stage: StageSummarySchema,
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
export const StageDeleteResponseSchema = Schema.Struct({
|
|
296
|
+
deletedStageSlug: Schema.String,
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
export const FeatureUsageSchema = Schema.Struct({
|
|
300
|
+
featureId: Schema.String,
|
|
301
|
+
allowed: Schema.Boolean,
|
|
302
|
+
usage: Schema.NullOr(Schema.Number.pipe(Schema.finite())),
|
|
303
|
+
includedUsage: Schema.NullOr(Schema.Number.pipe(Schema.finite())),
|
|
304
|
+
usageLimit: Schema.NullOr(Schema.Number.pipe(Schema.finite())),
|
|
305
|
+
overageAllowed: Schema.NullOr(Schema.Boolean),
|
|
306
|
+
nextResetAtMs: Schema.NullOr(Schema.Number.pipe(Schema.finite())),
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
export const BillingCatalogResponseSchema = Schema.Struct({
|
|
310
|
+
variants: Schema.Array(Schema.Unknown),
|
|
311
|
+
featureIds: Schema.Struct({
|
|
312
|
+
staticRequests: Schema.String,
|
|
313
|
+
dynamicRequests: Schema.String,
|
|
314
|
+
storageBytes: Schema.String,
|
|
315
|
+
}),
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
export const BillingStatusResponseSchema = Schema.Struct({
|
|
319
|
+
orgId: Schema.String,
|
|
320
|
+
orgRole: Schema.NullOr(Schema.String),
|
|
321
|
+
canManageBilling: Schema.Boolean,
|
|
322
|
+
currentProductId: Schema.NullOr(Schema.String),
|
|
323
|
+
currentTier: Schema.NullOr(Schema.String),
|
|
324
|
+
currentInterval: Schema.NullOr(Schema.String),
|
|
325
|
+
currentOverageMode: Schema.NullOr(Schema.String),
|
|
326
|
+
hasScheduledPlanChange: Schema.Boolean,
|
|
327
|
+
scheduledPlanChange: Schema.NullOr(Schema.Unknown),
|
|
328
|
+
usage: Schema.Struct({
|
|
329
|
+
staticRequests: FeatureUsageSchema,
|
|
330
|
+
dynamicRequests: FeatureUsageSchema,
|
|
331
|
+
storageBytes: FeatureUsageSchema,
|
|
332
|
+
}),
|
|
333
|
+
storageMirrorBytes: Schema.Number.pipe(Schema.finite()),
|
|
334
|
+
variants: Schema.Array(Schema.Unknown),
|
|
335
|
+
});
|
|
336
|
+
|
|
337
|
+
export const AuditEventSchema = Schema.Struct({
|
|
338
|
+
id: Schema.String,
|
|
339
|
+
orgId: Schema.String,
|
|
340
|
+
orgSlug: Schema.String,
|
|
341
|
+
projectId: Schema.NullOr(Schema.String),
|
|
342
|
+
projectSlug: Schema.NullOr(Schema.String),
|
|
343
|
+
stageSlug: Schema.NullOr(Schema.String),
|
|
344
|
+
eventType: Schema.String,
|
|
345
|
+
category: Schema.String,
|
|
346
|
+
occurredAtMs: Schema.Number.pipe(Schema.finite()),
|
|
347
|
+
actorSource: Schema.String,
|
|
348
|
+
actorClerkUserId: Schema.NullOr(Schema.String),
|
|
349
|
+
actorDisplayName: Schema.NullOr(Schema.String),
|
|
350
|
+
actorEmail: Schema.NullOr(Schema.String),
|
|
351
|
+
subjectType: Schema.String,
|
|
352
|
+
subjectId: Schema.NullOr(Schema.String),
|
|
353
|
+
subjectName: Schema.NullOr(Schema.String),
|
|
354
|
+
title: Schema.String,
|
|
355
|
+
description: Schema.String,
|
|
356
|
+
severity: Schema.String,
|
|
357
|
+
payloadJson: Schema.String,
|
|
358
|
+
retentionTier: Schema.String,
|
|
359
|
+
expiresAtMs: Schema.NullOr(Schema.Number.pipe(Schema.finite())),
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
export const AuditListResponseSchema = Schema.Struct({
|
|
363
|
+
items: Schema.Array(AuditEventSchema),
|
|
364
|
+
nextBeforeOccurredAtMs: Schema.NullOr(Schema.Number.pipe(Schema.finite())),
|
|
365
|
+
hasMore: Schema.Boolean,
|
|
366
|
+
});
|
|
367
|
+
|
|
368
|
+
export type CliConfigRecord = Schema.Schema.Type<typeof CliConfigSchema>;
|
|
369
|
+
export type CliSessionRecord = Schema.Schema.Type<typeof CliSessionSchema>;
|
|
370
|
+
export type TypegenManifest = Schema.Schema.Type<typeof TypegenManifestSchema>;
|
package/src/credentials-store.ts
CHANGED
|
@@ -2,13 +2,29 @@ import { mkdir, readFile, rm, writeFile } from "node:fs/promises";
|
|
|
2
2
|
import { homedir } from "node:os";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { spawn } from "node:child_process";
|
|
5
|
+
import { Either, Schema } from "effect";
|
|
5
6
|
|
|
7
|
+
import { CliConfigSchema, CliSessionSchema } from "./contracts/index.js";
|
|
6
8
|
import type { CliConfig, CliCredentials } from "./types.js";
|
|
7
9
|
|
|
8
10
|
const SERVICE_NAME = "barekey-cli";
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const
|
|
11
|
+
|
|
12
|
+
function resolveHomeDir(): string {
|
|
13
|
+
const configuredHome = process.env.HOME?.trim();
|
|
14
|
+
return configuredHome && configuredHome.length > 0 ? configuredHome : homedir();
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function getConfigDirPath(): string {
|
|
18
|
+
return path.join(resolveHomeDir(), ".config", "barekey");
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function getConfigPath(): string {
|
|
22
|
+
return path.join(getConfigDirPath(), "config.json");
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function getCredentialsDirPath(): string {
|
|
26
|
+
return path.join(getConfigDirPath(), "credentials");
|
|
27
|
+
}
|
|
12
28
|
|
|
13
29
|
type CommandResult = {
|
|
14
30
|
stdout: string;
|
|
@@ -48,7 +64,7 @@ function runCommand(command: string, args: Array<string>, input?: string): Promi
|
|
|
48
64
|
}
|
|
49
65
|
|
|
50
66
|
async function ensureConfigDir(): Promise<void> {
|
|
51
|
-
await mkdir(
|
|
67
|
+
await mkdir(getConfigDirPath(), {
|
|
52
68
|
recursive: true,
|
|
53
69
|
mode: 0o700,
|
|
54
70
|
});
|
|
@@ -56,7 +72,7 @@ async function ensureConfigDir(): Promise<void> {
|
|
|
56
72
|
|
|
57
73
|
async function ensureCredentialsDir(): Promise<void> {
|
|
58
74
|
await ensureConfigDir();
|
|
59
|
-
await mkdir(
|
|
75
|
+
await mkdir(getCredentialsDirPath(), {
|
|
60
76
|
recursive: true,
|
|
61
77
|
mode: 0o700,
|
|
62
78
|
});
|
|
@@ -80,7 +96,7 @@ async function writeJsonFile(filePath: string, value: unknown): Promise<void> {
|
|
|
80
96
|
}
|
|
81
97
|
|
|
82
98
|
function credentialsPathForAccount(accountId: string): string {
|
|
83
|
-
return path.join(
|
|
99
|
+
return path.join(getCredentialsDirPath(), `${encodeURIComponent(accountId)}.json`);
|
|
84
100
|
}
|
|
85
101
|
|
|
86
102
|
async function canUseLinuxSecretTool(): Promise<boolean> {
|
|
@@ -188,15 +204,37 @@ async function deleteFromKeychain(account: string): Promise<boolean> {
|
|
|
188
204
|
}
|
|
189
205
|
|
|
190
206
|
export async function saveConfig(config: CliConfig): Promise<void> {
|
|
191
|
-
await writeJsonFile(
|
|
207
|
+
await writeJsonFile(getConfigPath(), config);
|
|
192
208
|
}
|
|
193
209
|
|
|
194
210
|
export async function loadConfig(): Promise<CliConfig | null> {
|
|
195
|
-
|
|
211
|
+
const decoded = await readJsonFile<unknown>(getConfigPath());
|
|
212
|
+
if (decoded === null) {
|
|
213
|
+
return null;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
const result = Schema.decodeUnknownEither(
|
|
217
|
+
CliConfigSchema as unknown as Schema.Schema<any, any, never>,
|
|
218
|
+
)(decoded);
|
|
219
|
+
if (Either.isLeft(result)) {
|
|
220
|
+
return null;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
if ("activeSessionId" in result.right) {
|
|
224
|
+
return {
|
|
225
|
+
baseUrl: result.right.baseUrl,
|
|
226
|
+
activeSessionId: result.right.activeSessionId,
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
return {
|
|
231
|
+
baseUrl: result.right.baseUrl,
|
|
232
|
+
activeSessionId: result.right.activeAccountId,
|
|
233
|
+
};
|
|
196
234
|
}
|
|
197
235
|
|
|
198
236
|
export async function clearConfig(): Promise<void> {
|
|
199
|
-
await rm(
|
|
237
|
+
await rm(getConfigPath(), {
|
|
200
238
|
force: true,
|
|
201
239
|
});
|
|
202
240
|
}
|
|
@@ -225,14 +263,50 @@ export async function loadCredentials(accountId: string): Promise<CliCredentials
|
|
|
225
263
|
const fromKeychain = await getFromKeychain(accountId);
|
|
226
264
|
if (fromKeychain !== null) {
|
|
227
265
|
try {
|
|
228
|
-
|
|
266
|
+
const decoded = Schema.decodeUnknownEither(
|
|
267
|
+
CliSessionSchema as unknown as Schema.Schema<any, any, never>,
|
|
268
|
+
)(JSON.parse(fromKeychain) as unknown);
|
|
269
|
+
if (Either.isRight(decoded)) {
|
|
270
|
+
return {
|
|
271
|
+
accessToken: decoded.right.accessToken,
|
|
272
|
+
refreshToken: decoded.right.refreshToken,
|
|
273
|
+
accessTokenExpiresAtMs: decoded.right.accessTokenExpiresAtMs,
|
|
274
|
+
refreshTokenExpiresAtMs: decoded.right.refreshTokenExpiresAtMs,
|
|
275
|
+
clerkUserId: decoded.right.clerkUserId,
|
|
276
|
+
orgId: decoded.right.orgId ?? null,
|
|
277
|
+
orgSlug: decoded.right.orgSlug ?? null,
|
|
278
|
+
lastOrgId: ("lastOrgId" in decoded.right ? decoded.right.lastOrgId : undefined) ?? decoded.right.orgId ?? null,
|
|
279
|
+
lastOrgSlug: ("lastOrgSlug" in decoded.right ? decoded.right.lastOrgSlug : undefined) ?? decoded.right.orgSlug ?? null,
|
|
280
|
+
};
|
|
281
|
+
}
|
|
229
282
|
} catch {
|
|
230
283
|
// Fall back to file credentials when keychain data is malformed.
|
|
231
284
|
}
|
|
232
285
|
}
|
|
233
286
|
|
|
234
|
-
const fromFile = await readJsonFile<
|
|
235
|
-
|
|
287
|
+
const fromFile = await readJsonFile<unknown>(credentialsPathForAccount(accountId));
|
|
288
|
+
if (fromFile === null) {
|
|
289
|
+
return null;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
const decoded = Schema.decodeUnknownEither(
|
|
293
|
+
CliSessionSchema as unknown as Schema.Schema<any, any, never>,
|
|
294
|
+
)(fromFile);
|
|
295
|
+
if (Either.isLeft(decoded)) {
|
|
296
|
+
return null;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
return {
|
|
300
|
+
accessToken: decoded.right.accessToken,
|
|
301
|
+
refreshToken: decoded.right.refreshToken,
|
|
302
|
+
accessTokenExpiresAtMs: decoded.right.accessTokenExpiresAtMs,
|
|
303
|
+
refreshTokenExpiresAtMs: decoded.right.refreshTokenExpiresAtMs,
|
|
304
|
+
clerkUserId: decoded.right.clerkUserId,
|
|
305
|
+
orgId: decoded.right.orgId ?? null,
|
|
306
|
+
orgSlug: decoded.right.orgSlug ?? null,
|
|
307
|
+
lastOrgId: ("lastOrgId" in decoded.right ? decoded.right.lastOrgId : undefined) ?? decoded.right.orgId ?? null,
|
|
308
|
+
lastOrgSlug: ("lastOrgSlug" in decoded.right ? decoded.right.lastOrgSlug : undefined) ?? decoded.right.orgSlug ?? null,
|
|
309
|
+
};
|
|
236
310
|
}
|
|
237
311
|
|
|
238
312
|
export async function deleteCredentials(accountId: string): Promise<void> {
|
package/src/http.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { Effect, Either, Schema } from "effect";
|
|
2
|
+
|
|
1
3
|
export class CliHttpError extends Error {
|
|
2
4
|
readonly code: string;
|
|
3
5
|
readonly status: number;
|
|
@@ -20,11 +22,27 @@ async function parseJson(response: Response): Promise<unknown> {
|
|
|
20
22
|
}
|
|
21
23
|
}
|
|
22
24
|
|
|
25
|
+
function decodeResponse<TResponse>(
|
|
26
|
+
schema: Schema.Schema<TResponse>,
|
|
27
|
+
payload: unknown,
|
|
28
|
+
): TResponse {
|
|
29
|
+
const decoded = Schema.decodeUnknownEither(schema)(payload);
|
|
30
|
+
if (Either.isLeft(decoded)) {
|
|
31
|
+
throw new CliHttpError({
|
|
32
|
+
code: "INVALID_RESPONSE",
|
|
33
|
+
status: 500,
|
|
34
|
+
message: "Barekey returned an unexpected response payload.",
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
return decoded.right;
|
|
38
|
+
}
|
|
39
|
+
|
|
23
40
|
export async function postJson<TResponse>(input: {
|
|
24
41
|
baseUrl: string;
|
|
25
42
|
path: string;
|
|
26
43
|
payload: unknown;
|
|
27
44
|
accessToken?: string | null;
|
|
45
|
+
schema?: Schema.Schema<TResponse>;
|
|
28
46
|
}): Promise<TResponse> {
|
|
29
47
|
const response = await fetch(`${input.baseUrl.replace(/\/$/, "")}${input.path}`, {
|
|
30
48
|
method: "POST",
|
|
@@ -52,13 +70,14 @@ export async function postJson<TResponse>(input: {
|
|
|
52
70
|
});
|
|
53
71
|
}
|
|
54
72
|
|
|
55
|
-
return parsed as TResponse;
|
|
73
|
+
return input.schema ? decodeResponse(input.schema, parsed) : (parsed as TResponse);
|
|
56
74
|
}
|
|
57
75
|
|
|
58
76
|
export async function getJson<TResponse>(input: {
|
|
59
77
|
baseUrl: string;
|
|
60
78
|
path: string;
|
|
61
79
|
accessToken?: string | null;
|
|
80
|
+
schema?: Schema.Schema<TResponse>;
|
|
62
81
|
}): Promise<TResponse> {
|
|
63
82
|
const response = await fetch(`${input.baseUrl.replace(/\/$/, "")}${input.path}`, {
|
|
64
83
|
method: "GET",
|
|
@@ -82,5 +101,62 @@ export async function getJson<TResponse>(input: {
|
|
|
82
101
|
});
|
|
83
102
|
}
|
|
84
103
|
|
|
85
|
-
return parsed as TResponse;
|
|
104
|
+
return input.schema ? decodeResponse(input.schema, parsed) : (parsed as TResponse);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Executes one typed HTTP POST request as an Effect program.
|
|
109
|
+
*
|
|
110
|
+
* @param input The request configuration and response schema.
|
|
111
|
+
* @returns An Effect that succeeds with the decoded JSON response.
|
|
112
|
+
* @remarks CLI command programs use this so schema decode failures and transport failures share one typed path.
|
|
113
|
+
* @lastModified 2026-03-19
|
|
114
|
+
* @author GPT-5.4
|
|
115
|
+
*/
|
|
116
|
+
export function postJsonEffect<TResponse>(input: {
|
|
117
|
+
baseUrl: string;
|
|
118
|
+
path: string;
|
|
119
|
+
payload: unknown;
|
|
120
|
+
accessToken?: string | null;
|
|
121
|
+
schema: Schema.Schema<TResponse>;
|
|
122
|
+
}) {
|
|
123
|
+
return Effect.tryPromise({
|
|
124
|
+
try: () => postJson(input),
|
|
125
|
+
catch: (error) =>
|
|
126
|
+
error instanceof CliHttpError
|
|
127
|
+
? error
|
|
128
|
+
: new CliHttpError({
|
|
129
|
+
code: "HTTP_ERROR",
|
|
130
|
+
status: 500,
|
|
131
|
+
message: error instanceof Error ? error.message : "HTTP request failed.",
|
|
132
|
+
}),
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Executes one typed HTTP GET request as an Effect program.
|
|
138
|
+
*
|
|
139
|
+
* @param input The request configuration and response schema.
|
|
140
|
+
* @returns An Effect that succeeds with the decoded JSON response.
|
|
141
|
+
* @remarks CLI command programs use this so schema decode failures and transport failures share one typed path.
|
|
142
|
+
* @lastModified 2026-03-19
|
|
143
|
+
* @author GPT-5.4
|
|
144
|
+
*/
|
|
145
|
+
export function getJsonEffect<TResponse>(input: {
|
|
146
|
+
baseUrl: string;
|
|
147
|
+
path: string;
|
|
148
|
+
accessToken?: string | null;
|
|
149
|
+
schema: Schema.Schema<TResponse>;
|
|
150
|
+
}) {
|
|
151
|
+
return Effect.tryPromise({
|
|
152
|
+
try: () => getJson(input),
|
|
153
|
+
catch: (error) =>
|
|
154
|
+
error instanceof CliHttpError
|
|
155
|
+
? error
|
|
156
|
+
: new CliHttpError({
|
|
157
|
+
code: "HTTP_ERROR",
|
|
158
|
+
status: 500,
|
|
159
|
+
message: error instanceof Error ? error.message : "HTTP request failed.",
|
|
160
|
+
}),
|
|
161
|
+
});
|
|
86
162
|
}
|
package/src/index.ts
CHANGED
|
@@ -3,7 +3,13 @@ import { Command } from "commander";
|
|
|
3
3
|
import pc from "picocolors";
|
|
4
4
|
|
|
5
5
|
import { registerAuthCommands } from "./commands/auth.js";
|
|
6
|
+
import { registerAuditCommands } from "./commands/audit.js";
|
|
7
|
+
import { registerBillingCommands } from "./commands/billing.js";
|
|
6
8
|
import { registerEnvCommands } from "./commands/env.js";
|
|
9
|
+
import { registerInitCommand } from "./commands/init.js";
|
|
10
|
+
import { registerOrgCommands } from "./commands/org.js";
|
|
11
|
+
import { registerProjectCommands } from "./commands/project.js";
|
|
12
|
+
import { registerStageCommands } from "./commands/stage.js";
|
|
7
13
|
import { registerTypegenCommand } from "./commands/typegen.js";
|
|
8
14
|
import { CLI_DESCRIPTION, CLI_NAME, CLI_VERSION } from "./constants.js";
|
|
9
15
|
|
|
@@ -11,6 +17,12 @@ const program = new Command();
|
|
|
11
17
|
program.name(CLI_NAME).description(CLI_DESCRIPTION).version(CLI_VERSION);
|
|
12
18
|
|
|
13
19
|
registerAuthCommands(program);
|
|
20
|
+
registerAuditCommands(program);
|
|
21
|
+
registerBillingCommands(program);
|
|
22
|
+
registerInitCommand(program);
|
|
23
|
+
registerOrgCommands(program);
|
|
24
|
+
registerProjectCommands(program);
|
|
25
|
+
registerStageCommands(program);
|
|
14
26
|
registerEnvCommands(program);
|
|
15
27
|
registerTypegenCommand(program);
|
|
16
28
|
|