@amerged/ohmyhost-cli 0.1.41 → 0.1.42

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.
@@ -20,6 +20,36 @@ import {
20
20
  type ProjectDatabaseWriteReceipt,
21
21
  } from "@ohmyhost/contracts/database-access";
22
22
  import { assertDatabaseCompute, type DatabaseCompute } from "@ohmyhost/contracts/database-compute";
23
+ import {
24
+ assertDatabaseExecutionUsagePage,
25
+ assertDatabaseSchedule,
26
+ assertDatabaseSchedulePage,
27
+ assertDatabaseScheduleDeleted,
28
+ assertDatabaseScheduleRunAccepted,
29
+ assertDatabaseScheduleRunPage,
30
+ assertDatabaseWebhook,
31
+ assertDatabaseWebhookCreated,
32
+ assertDatabaseWebhookDeleted,
33
+ assertDatabaseWebhookDeliveryPage,
34
+ assertDatabaseWebhookPage,
35
+ assertDatabaseWebhookReplayAccepted,
36
+ assertDatabaseWebhookTest,
37
+ type DatabaseExecutionUsagePage,
38
+ type DatabaseSchedule,
39
+ type DatabaseScheduleDeleted,
40
+ type DatabaseSchedulePage,
41
+ type DatabaseScheduleRunAccepted,
42
+ type DatabaseScheduleRunPage,
43
+ type DatabaseScheduleSetRequest,
44
+ type DatabaseWebhook,
45
+ type DatabaseWebhookCreated,
46
+ type DatabaseWebhookDeleted,
47
+ type DatabaseWebhookDeliveryPage,
48
+ type DatabaseWebhookEventType,
49
+ type DatabaseWebhookPage,
50
+ type DatabaseWebhookReplayAccepted,
51
+ type DatabaseWebhookTestResult,
52
+ } from "@ohmyhost/contracts/database-events";
23
53
  import type { DatabaseComputeSelection } from "@ohmyhost/contracts/database-sizes";
24
54
  import {
25
55
  assertProjectContext,
@@ -117,6 +147,20 @@ import {
117
147
  createProjectDatabaseAccess,
118
148
  listProjectDatabaseAccess,
119
149
  revokeProjectDatabaseAccess,
150
+ createProjectDatabaseWebhook,
151
+ listProjectDatabaseWebhooks,
152
+ getProjectDatabaseWebhook,
153
+ deleteProjectDatabaseWebhook,
154
+ testProjectDatabaseWebhook,
155
+ listProjectDatabaseWebhookDeliveries,
156
+ replayProjectDatabaseWebhookDelivery,
157
+ setProjectDatabaseSchedule,
158
+ listProjectDatabaseSchedules,
159
+ getProjectDatabaseSchedule,
160
+ deleteProjectDatabaseSchedule,
161
+ listProjectDatabaseScheduleRuns,
162
+ runProjectDatabaseSchedule,
163
+ getProjectDatabaseExecutionUsage,
120
164
  reconcileOperation,
121
165
  streamOperationEvents,
122
166
  type DeploymentPlan,
@@ -279,6 +323,85 @@ export interface ProductApi {
279
323
  readonly projectId: string;
280
324
  readonly accessId: string;
281
325
  }): Promise<ProjectDatabaseAccess>;
326
+ createProjectDatabaseWebhook(input: {
327
+ readonly projectId: string;
328
+ readonly environment: "dev" | "prod";
329
+ readonly idempotencyKey: string;
330
+ readonly url: string;
331
+ readonly eventTypes: readonly DatabaseWebhookEventType[];
332
+ readonly headers: Readonly<Record<string, string>>;
333
+ }): Promise<DatabaseWebhookCreated>;
334
+ listProjectDatabaseWebhooks(input: {
335
+ readonly projectId: string;
336
+ readonly environment: "dev" | "prod";
337
+ }): Promise<DatabaseWebhookPage>;
338
+ getProjectDatabaseWebhook(input: {
339
+ readonly projectId: string;
340
+ readonly environment: "dev" | "prod";
341
+ readonly webhookId: string;
342
+ }): Promise<DatabaseWebhook>;
343
+ deleteProjectDatabaseWebhook(input: {
344
+ readonly projectId: string;
345
+ readonly environment: "dev" | "prod";
346
+ readonly webhookId: string;
347
+ }): Promise<DatabaseWebhookDeleted>;
348
+ testProjectDatabaseWebhook(input: {
349
+ readonly projectId: string;
350
+ readonly environment: "dev" | "prod";
351
+ readonly webhookId: string;
352
+ }): Promise<DatabaseWebhookTestResult>;
353
+ listProjectDatabaseWebhookDeliveries(input: {
354
+ readonly projectId: string;
355
+ readonly environment: "dev" | "prod";
356
+ readonly webhookId?: string;
357
+ readonly limit?: number;
358
+ readonly cursor?: string;
359
+ }): Promise<DatabaseWebhookDeliveryPage>;
360
+ replayProjectDatabaseWebhookDelivery(input: {
361
+ readonly projectId: string;
362
+ readonly environment: "dev" | "prod";
363
+ readonly deliveryId: string;
364
+ }): Promise<DatabaseWebhookReplayAccepted>;
365
+ setProjectDatabaseSchedule(input: {
366
+ readonly projectId: string;
367
+ readonly environment: "dev" | "prod";
368
+ readonly name: string;
369
+ readonly request: DatabaseScheduleSetRequest;
370
+ }): Promise<DatabaseSchedule>;
371
+ listProjectDatabaseSchedules(input: {
372
+ readonly projectId: string;
373
+ readonly environment: "dev" | "prod";
374
+ }): Promise<DatabaseSchedulePage>;
375
+ getProjectDatabaseSchedule(input: {
376
+ readonly projectId: string;
377
+ readonly environment: "dev" | "prod";
378
+ readonly name: string;
379
+ }): Promise<DatabaseSchedule>;
380
+ deleteProjectDatabaseSchedule(input: {
381
+ readonly projectId: string;
382
+ readonly environment: "dev" | "prod";
383
+ readonly name: string;
384
+ }): Promise<DatabaseScheduleDeleted>;
385
+ listProjectDatabaseScheduleRuns(input: {
386
+ readonly projectId: string;
387
+ readonly environment: "dev" | "prod";
388
+ readonly name: string;
389
+ readonly limit?: number;
390
+ }): Promise<DatabaseScheduleRunPage>;
391
+ runProjectDatabaseSchedule(input: {
392
+ readonly projectId: string;
393
+ readonly environment: "dev" | "prod";
394
+ readonly name: string;
395
+ }): Promise<DatabaseScheduleRunAccepted>;
396
+ getProjectDatabaseExecutionUsage(input: {
397
+ readonly projectId: string;
398
+ readonly environment: "dev" | "prod";
399
+ readonly from: string;
400
+ readonly to: string;
401
+ readonly granularity: "hour" | "day";
402
+ readonly limit?: number;
403
+ readonly cursor?: string;
404
+ }): Promise<DatabaseExecutionUsagePage>;
282
405
  planPaidDomain(input: {
283
406
  readonly projectId: string;
284
407
  readonly hostname: string;
@@ -441,6 +564,11 @@ export interface ProductApi {
441
564
  managedMail?(input: ManagedMailCommand): Promise<unknown>;
442
565
  }
443
566
 
567
+ /** A webhook answer that names another environment, webhook or delivery than the request did. */
568
+ const WEBHOOK_SCOPE_MISMATCH = "Webhook response scope mismatch";
569
+ /** A schedule answer that names another environment or schedule than the request did. */
570
+ const SCHEDULE_SCOPE_MISMATCH = "Schedule response scope mismatch";
571
+
444
572
  export class GeneratedSdkProductApi implements ProductApi {
445
573
  readonly #client: OhMyHostClient;
446
574
  public readonly managedSource: ManagedSourceApi;
@@ -761,6 +889,241 @@ export class GeneratedSdkProductApi implements ProductApi {
761
889
  return value;
762
890
  }
763
891
 
892
+ /** The signing secret exists only in this answer; the CLI prints it once and stores nothing. */
893
+ public async createProjectDatabaseWebhook(
894
+ input: Parameters<ProductApi["createProjectDatabaseWebhook"]>[0],
895
+ ): Promise<DatabaseWebhookCreated> {
896
+ const value = await createProjectDatabaseWebhook(
897
+ {
898
+ project_id: input.projectId,
899
+ environment: input.environment,
900
+ "Idempotency-Key": input.idempotencyKey,
901
+ databaseWebhookCreateRequest: {
902
+ url: input.url,
903
+ event_types: [...input.eventTypes],
904
+ headers: { ...input.headers },
905
+ },
906
+ },
907
+ { client: this.#client },
908
+ );
909
+ assertDatabaseWebhookCreated(value);
910
+ if (value.environment !== input.environment) throw new TypeError(WEBHOOK_SCOPE_MISMATCH);
911
+ return value;
912
+ }
913
+
914
+ public async listProjectDatabaseWebhooks(
915
+ input: Parameters<ProductApi["listProjectDatabaseWebhooks"]>[0],
916
+ ): Promise<DatabaseWebhookPage> {
917
+ const value = await listProjectDatabaseWebhooks(
918
+ { project_id: input.projectId, environment: input.environment },
919
+ { client: this.#client },
920
+ );
921
+ assertDatabaseWebhookPage(value);
922
+ if (value.items.some((item) => item.environment !== input.environment))
923
+ throw new TypeError(WEBHOOK_SCOPE_MISMATCH);
924
+ return value;
925
+ }
926
+
927
+ public async getProjectDatabaseWebhook(
928
+ input: Parameters<ProductApi["getProjectDatabaseWebhook"]>[0],
929
+ ): Promise<DatabaseWebhook> {
930
+ const value = await getProjectDatabaseWebhook(
931
+ {
932
+ project_id: input.projectId,
933
+ environment: input.environment,
934
+ webhook_id: input.webhookId,
935
+ },
936
+ { client: this.#client },
937
+ );
938
+ assertDatabaseWebhook(value);
939
+ if (value.id !== input.webhookId || value.environment !== input.environment)
940
+ throw new TypeError(WEBHOOK_SCOPE_MISMATCH);
941
+ return value;
942
+ }
943
+
944
+ public async deleteProjectDatabaseWebhook(
945
+ input: Parameters<ProductApi["deleteProjectDatabaseWebhook"]>[0],
946
+ ): Promise<DatabaseWebhookDeleted> {
947
+ const value = await deleteProjectDatabaseWebhook(
948
+ {
949
+ project_id: input.projectId,
950
+ environment: input.environment,
951
+ webhook_id: input.webhookId,
952
+ },
953
+ { client: this.#client },
954
+ );
955
+ assertDatabaseWebhookDeleted(value);
956
+ if (value.id !== input.webhookId) throw new TypeError(WEBHOOK_SCOPE_MISMATCH);
957
+ return value;
958
+ }
959
+
960
+ public async testProjectDatabaseWebhook(
961
+ input: Parameters<ProductApi["testProjectDatabaseWebhook"]>[0],
962
+ ): Promise<DatabaseWebhookTestResult> {
963
+ const value = await testProjectDatabaseWebhook(
964
+ {
965
+ project_id: input.projectId,
966
+ environment: input.environment,
967
+ webhook_id: input.webhookId,
968
+ },
969
+ { client: this.#client },
970
+ );
971
+ assertDatabaseWebhookTest(value);
972
+ return value;
973
+ }
974
+
975
+ public async listProjectDatabaseWebhookDeliveries(
976
+ input: Parameters<ProductApi["listProjectDatabaseWebhookDeliveries"]>[0],
977
+ ): Promise<DatabaseWebhookDeliveryPage> {
978
+ const value = await listProjectDatabaseWebhookDeliveries(
979
+ {
980
+ project_id: input.projectId,
981
+ environment: input.environment,
982
+ ...(input.webhookId === undefined ? {} : { webhook_id: input.webhookId }),
983
+ ...(input.limit === undefined ? {} : { limit: input.limit }),
984
+ ...(input.cursor === undefined ? {} : { cursor: input.cursor }),
985
+ },
986
+ { client: this.#client },
987
+ );
988
+ assertDatabaseWebhookDeliveryPage(value);
989
+ if (
990
+ input.webhookId !== undefined &&
991
+ value.items.some((item) => item.webhook_id !== input.webhookId)
992
+ )
993
+ throw new TypeError(WEBHOOK_SCOPE_MISMATCH);
994
+ return value;
995
+ }
996
+
997
+ public async replayProjectDatabaseWebhookDelivery(
998
+ input: Parameters<ProductApi["replayProjectDatabaseWebhookDelivery"]>[0],
999
+ ): Promise<DatabaseWebhookReplayAccepted> {
1000
+ const value = await replayProjectDatabaseWebhookDelivery(
1001
+ {
1002
+ project_id: input.projectId,
1003
+ environment: input.environment,
1004
+ delivery_id: input.deliveryId,
1005
+ },
1006
+ { client: this.#client },
1007
+ );
1008
+ assertDatabaseWebhookReplayAccepted(value);
1009
+ if (value.delivery_id !== input.deliveryId) throw new TypeError(WEBHOOK_SCOPE_MISMATCH);
1010
+ return value;
1011
+ }
1012
+
1013
+ /** A schedule runs the statements as the application's runtime role; the request confirms it. */
1014
+ public async setProjectDatabaseSchedule(
1015
+ input: Parameters<ProductApi["setProjectDatabaseSchedule"]>[0],
1016
+ ): Promise<DatabaseSchedule> {
1017
+ const request = input.request;
1018
+ const value = await setProjectDatabaseSchedule(
1019
+ {
1020
+ project_id: input.projectId,
1021
+ environment: input.environment,
1022
+ name: input.name,
1023
+ databaseScheduleSetRequest: {
1024
+ ...(request.cron === null ? {} : { cron: request.cron }),
1025
+ ...(request.every_seconds === null ? {} : { every_seconds: request.every_seconds }),
1026
+ statements: [...request.statements],
1027
+ timeout_ms: request.timeout_ms,
1028
+ enabled: request.enabled,
1029
+ confirm: true,
1030
+ },
1031
+ },
1032
+ { client: this.#client },
1033
+ );
1034
+ assertDatabaseSchedule(value);
1035
+ if (value.name !== input.name || value.environment !== input.environment)
1036
+ throw new TypeError(SCHEDULE_SCOPE_MISMATCH);
1037
+ return value;
1038
+ }
1039
+
1040
+ public async listProjectDatabaseSchedules(
1041
+ input: Parameters<ProductApi["listProjectDatabaseSchedules"]>[0],
1042
+ ): Promise<DatabaseSchedulePage> {
1043
+ const value = await listProjectDatabaseSchedules(
1044
+ { project_id: input.projectId, environment: input.environment },
1045
+ { client: this.#client },
1046
+ );
1047
+ assertDatabaseSchedulePage(value);
1048
+ if (value.items.some((item) => item.environment !== input.environment))
1049
+ throw new TypeError(SCHEDULE_SCOPE_MISMATCH);
1050
+ return value;
1051
+ }
1052
+
1053
+ public async getProjectDatabaseSchedule(
1054
+ input: Parameters<ProductApi["getProjectDatabaseSchedule"]>[0],
1055
+ ): Promise<DatabaseSchedule> {
1056
+ const value = await getProjectDatabaseSchedule(
1057
+ { project_id: input.projectId, environment: input.environment, name: input.name },
1058
+ { client: this.#client },
1059
+ );
1060
+ assertDatabaseSchedule(value);
1061
+ if (value.name !== input.name || value.environment !== input.environment)
1062
+ throw new TypeError(SCHEDULE_SCOPE_MISMATCH);
1063
+ return value;
1064
+ }
1065
+
1066
+ public async deleteProjectDatabaseSchedule(
1067
+ input: Parameters<ProductApi["deleteProjectDatabaseSchedule"]>[0],
1068
+ ): Promise<DatabaseScheduleDeleted> {
1069
+ const value = await deleteProjectDatabaseSchedule(
1070
+ { project_id: input.projectId, environment: input.environment, name: input.name },
1071
+ { client: this.#client },
1072
+ );
1073
+ assertDatabaseScheduleDeleted(value);
1074
+ if (value.name !== input.name) throw new TypeError(SCHEDULE_SCOPE_MISMATCH);
1075
+ return value;
1076
+ }
1077
+
1078
+ public async listProjectDatabaseScheduleRuns(
1079
+ input: Parameters<ProductApi["listProjectDatabaseScheduleRuns"]>[0],
1080
+ ): Promise<DatabaseScheduleRunPage> {
1081
+ const value = await listProjectDatabaseScheduleRuns(
1082
+ {
1083
+ project_id: input.projectId,
1084
+ environment: input.environment,
1085
+ name: input.name,
1086
+ ...(input.limit === undefined ? {} : { limit: input.limit }),
1087
+ },
1088
+ { client: this.#client },
1089
+ );
1090
+ assertDatabaseScheduleRunPage(value);
1091
+ if (value.items.some((item) => item.schedule !== input.name))
1092
+ throw new TypeError(SCHEDULE_SCOPE_MISMATCH);
1093
+ return value;
1094
+ }
1095
+
1096
+ public async runProjectDatabaseSchedule(
1097
+ input: Parameters<ProductApi["runProjectDatabaseSchedule"]>[0],
1098
+ ): Promise<DatabaseScheduleRunAccepted> {
1099
+ const value = await runProjectDatabaseSchedule(
1100
+ { project_id: input.projectId, environment: input.environment, name: input.name },
1101
+ { client: this.#client },
1102
+ );
1103
+ assertDatabaseScheduleRunAccepted(value);
1104
+ if (value.schedule !== input.name) throw new TypeError(SCHEDULE_SCOPE_MISMATCH);
1105
+ return value;
1106
+ }
1107
+
1108
+ public async getProjectDatabaseExecutionUsage(
1109
+ input: Parameters<ProductApi["getProjectDatabaseExecutionUsage"]>[0],
1110
+ ): Promise<DatabaseExecutionUsagePage> {
1111
+ const value = await getProjectDatabaseExecutionUsage(
1112
+ {
1113
+ project_id: input.projectId,
1114
+ environment: input.environment,
1115
+ from: input.from,
1116
+ to: input.to,
1117
+ granularity: input.granularity,
1118
+ ...(input.limit === undefined ? {} : { limit: input.limit }),
1119
+ ...(input.cursor === undefined ? {} : { cursor: input.cursor }),
1120
+ },
1121
+ { client: this.#client },
1122
+ );
1123
+ assertDatabaseExecutionUsagePage(value);
1124
+ return value;
1125
+ }
1126
+
764
1127
  public async planPaidDomain(input: {
765
1128
  readonly projectId: string;
766
1129
  readonly hostname: string;
@@ -127,6 +127,11 @@
127
127
  "types": "./dist/database-access.d.ts",
128
128
  "import": "./dist/database-access.js"
129
129
  },
130
+ "./database-events": {
131
+ "source": "./src/database-events.ts",
132
+ "types": "./dist/database-events.d.ts",
133
+ "import": "./dist/database-events.js"
134
+ },
130
135
  "./functions": {
131
136
  "source": "./src/functions.ts",
132
137
  "types": "./dist/functions.d.ts",
@@ -112,21 +112,12 @@ export interface ProjectDatabaseAccessFields {
112
112
  | "data_change"
113
113
  | null;
114
114
  }
115
- export type ProjectDatabaseAccess = ProjectDatabaseAccessFields &
116
- (
117
- | {
118
- readonly database: "neondb";
119
- readonly provider?: never;
120
- readonly transport?: never;
121
- readonly websocket_url?: never;
122
- }
123
- | {
124
- readonly provider: "pgcf";
125
- readonly transport: "wss";
126
- readonly websocket_url: string;
127
- readonly database: string;
128
- }
129
- );
115
+ export type ProjectDatabaseAccess = ProjectDatabaseAccessFields & {
116
+ readonly provider: "pgcf";
117
+ readonly transport: "wss";
118
+ readonly websocket_url: string;
119
+ readonly database: string;
120
+ };
130
121
  export type ProjectDatabaseAccessCredential = ProjectDatabaseAccess & {
131
122
  readonly connection_uri: string;
132
123
  readonly psql_command: string;
@@ -140,6 +131,9 @@ const ACCESS_KEYS = [
140
131
  "mode",
141
132
  "role_name",
142
133
  "host",
134
+ "provider",
135
+ "transport",
136
+ "websocket_url",
143
137
  "database",
144
138
  "label",
145
139
  "state",
@@ -177,26 +171,23 @@ export function parseProjectDatabaseAccessRequest(value: unknown): ProjectDataba
177
171
  export function assertProjectDatabaseAccess(
178
172
  value: unknown,
179
173
  ): asserts value is ProjectDatabaseAccess {
180
- if (!record(value) || !exact(value, accessKeys(value)))
181
- throw new TypeError("Invalid database access");
174
+ if (!record(value) || !exact(value, ACCESS_KEYS)) throw new TypeError("Invalid database access");
182
175
  assertAccessFields(value);
183
176
  }
184
177
  export function assertProjectDatabaseAccessCredential(
185
178
  value: unknown,
186
179
  ): asserts value is ProjectDatabaseAccessCredential {
187
- if (!record(value) || !exact(value, [...accessKeys(value), "connection_uri", "psql_command"]))
180
+ if (!record(value) || !exact(value, [...ACCESS_KEYS, "connection_uri", "psql_command"]))
188
181
  throw new TypeError("Invalid database access credential");
189
182
  assertAccessFields(value);
190
183
  const uri = value["connection_uri"];
191
184
  if (
192
185
  typeof uri !== "string" ||
193
- (value["provider"] === "pgcf"
194
- ? typeof value["psql_command"] !== "string" ||
195
- !new RegExp(
196
- `^ohmyhost database psql --project [0-7][0-9A-HJKMNP-TV-Z]{25} --environment ${value["environment"]} --mode ${value["mode"]}$`,
197
- "u",
198
- ).test(value["psql_command"])
199
- : value["psql_command"] !== `psql '${uri}'`)
186
+ typeof value["psql_command"] !== "string" ||
187
+ !new RegExp(
188
+ `^ohmyhost database psql --project [0-7][0-9A-HJKMNP-TV-Z]{25} --environment ${value["environment"]} --mode ${value["mode"]}$`,
189
+ "u",
190
+ ).test(value["psql_command"])
200
191
  )
201
192
  throw new TypeError("Invalid database access credential");
202
193
  let parsed: URL;
@@ -206,20 +197,14 @@ export function assertProjectDatabaseAccessCredential(
206
197
  throw new TypeError("Invalid database access credential");
207
198
  }
208
199
  if (
209
- (value["provider"] === "pgcf"
210
- ? !["postgres:", "postgresql:"].includes(parsed.protocol)
211
- : parsed.protocol !== "postgresql:") ||
200
+ !["postgres:", "postgresql:"].includes(parsed.protocol) ||
212
201
  decodeURIComponent(parsed.username) !== value["role_name"] ||
213
202
  parsed.password === "" ||
214
203
  parsed.hostname !== value["host"] ||
215
- (value["provider"] === "pgcf"
216
- ? parsed.port !== "" && parsed.port !== "5432"
217
- : parsed.host !== value["host"]) ||
204
+ (parsed.port !== "" && parsed.port !== "5432") ||
218
205
  decodeURIComponent(parsed.pathname.slice(1)) !== value["database"] ||
219
206
  parsed.hash !== "" ||
220
- (value["provider"] === "pgcf"
221
- ? !["", "?sslmode=require", "?sslmode=verify-full"].includes(parsed.search)
222
- : parsed.search !== "?sslmode=require")
207
+ !["", "?sslmode=require", "?sslmode=verify-full"].includes(parsed.search)
223
208
  )
224
209
  throw new TypeError("Invalid database access credential");
225
210
  }
@@ -235,11 +220,6 @@ export function assertProjectDatabaseAccessPage(
235
220
  throw new TypeError("Invalid database access page");
236
221
  for (const item of value["items"]) assertProjectDatabaseAccess(item);
237
222
  }
238
- function accessKeys(value: Record<string, unknown>): readonly string[] {
239
- return value["provider"] === "pgcf"
240
- ? [...ACCESS_KEYS, "provider", "transport", "websocket_url"]
241
- : ACCESS_KEYS;
242
- }
243
223
  function assertAccessFields(value: Record<string, unknown>): void {
244
224
  const revoked = value["revoked_at"],
245
225
  reason = value["revocation_reason"];
@@ -252,12 +232,11 @@ function assertAccessFields(value: Record<string, unknown>): void {
252
232
  !ACCESS_ROLE_PATTERN.test(value["role_name"]) ||
253
233
  typeof value["host"] !== "string" ||
254
234
  !/^[a-z0-9]([a-z0-9.-]{0,251}[a-z0-9])?$/u.test(value["host"]) ||
255
- (value["provider"] === "pgcf"
256
- ? typeof value["database"] !== "string" ||
257
- !/^[a-z][a-z0-9]{19}$/u.test(value["database"]) ||
258
- value["transport"] !== "wss" ||
259
- value["websocket_url"] !== `wss://${value["host"]}/`
260
- : value["database"] !== "neondb") ||
235
+ value["provider"] !== "pgcf" ||
236
+ value["transport"] !== "wss" ||
237
+ value["websocket_url"] !== `wss://${value["host"]}/` ||
238
+ typeof value["database"] !== "string" ||
239
+ !/^[a-z][a-z0-9]{19}$/u.test(value["database"]) ||
261
240
  (value["label"] !== null && accessLabel(value["label"]) !== value["label"]) ||
262
241
  !["active", "expired", "revoked"].includes(String(value["state"])) ||
263
242
  !timestamp(value["issued_at"]) ||