@amerged/ohmyhost-cli 0.1.43 → 0.1.45
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 +1 -1
- package/dist/bin.js +1 -1
- package/dist/{chunk-5TO5I2HF.js → chunk-C6KEAOJP.js} +505 -14
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/src/apps/product-cli/package.json +1 -1
- package/src/apps/product-cli/src/cli.ts +64 -4
- package/src/apps/product-cli/src/command.ts +123 -2
- package/src/apps/product-cli/src/product-api.ts +86 -2
- package/src/packages/contracts/src/database-events.ts +208 -11
- package/src/packages/contracts/src/database-migration-admission.ts +22 -0
- package/src/packages/contracts/src/database-migration-capture.ts +177 -0
- package/src/packages/contracts/src/database-migration-lexical.ts +1 -0
- package/src/packages/contracts/src/operation-failure.ts +4 -4
- package/src/packages/contracts/src/problem-policy.ts +36 -1
- package/src/packages/sdk-ts/package.json +1 -1
- package/src/packages/sdk-ts/src/generated/index.ts +25 -0
- package/src/packages/sdk-ts/src/generated/sdk.gen.ts +153 -3
- package/src/packages/sdk-ts/src/generated/types.gen.ts +274 -4
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -419,8 +419,14 @@ const HELP_USAGE = Object.freeze({
|
|
|
419
419
|
"ohmyhost database access list --project ULID [--environment dev|prod] --json",
|
|
420
420
|
"database access revoke":
|
|
421
421
|
"ohmyhost database access revoke --project ULID --access ULID --yes --json",
|
|
422
|
+
"database watch create":
|
|
423
|
+
"ohmyhost database watch create --project ULID --environment dev|prod --table NAME [--schema public] --columns COL[,COL] [--operations insert,update,delete] --idempotency-key KEY --yes --json (publishes only the listed columns, at most 32, of each row change as the event type data.<topic> printed in this answer; the table must exist as an ordinary table of the application; a sleeping database wakes; next, subscribe with 'ohmyhost database webhook create ... --event-types data.<topic>')",
|
|
424
|
+
"database watch list":
|
|
425
|
+
"ohmyhost database watch list --project ULID [--environment dev|prod] --json (dev when omitted; a sleeping database wakes)",
|
|
426
|
+
"database watch delete":
|
|
427
|
+
"ohmyhost database watch delete --project ULID --environment dev|prod --watch ID --idempotency-key KEY --yes --json",
|
|
422
428
|
"database webhook create":
|
|
423
|
-
"ohmyhost database webhook create --project ULID --environment dev|prod --url HTTPS_URL --event-types TYPE[,TYPE] [--headers-file PATH] --idempotency-key KEY --yes --json (the signing secret is shown once in this answer; types: database.created, database.ready, database.woke, database.slept, database.suspended, database.resized, database.deleted; the headers file is a UTF-8 JSON object of at most 8 KiB)",
|
|
429
|
+
"ohmyhost database webhook create --project ULID --environment dev|prod --url HTTPS_URL --event-types TYPE[,TYPE] [--headers-file PATH] --idempotency-key KEY --yes --json (the signing secret is shown once in this answer; types: database.created, database.ready, database.woke, database.slept, database.suspended, database.resized, database.deleted, data.<topic> for the rows of one watched table printed by database watch create, or data.* for every watched table; a bare * is not accepted and does not include data events; the headers file is a UTF-8 JSON object of at most 8 KiB)",
|
|
424
430
|
"database webhook list":
|
|
425
431
|
"ohmyhost database webhook list --project ULID [--environment dev|prod] --json (dev when omitted; the secret is never listed)",
|
|
426
432
|
"database webhook get":
|
|
@@ -434,7 +440,7 @@ const HELP_USAGE = Object.freeze({
|
|
|
434
440
|
"database webhook replay":
|
|
435
441
|
"ohmyhost database webhook replay --project ULID --environment dev|prod --delivery ID --yes --json",
|
|
436
442
|
"database schedule set":
|
|
437
|
-
"ohmyhost database schedule set --project ULID --environment dev|prod --name NAME (--cron EXPR | --every-seconds N) --statements-file PATH [--timeout-ms N] [--enabled true|false] --yes --json (runs the statements in the file, a UTF-8 JSON array of 1 to 20 SQL strings, as the runtime role of the application; cron has five fields in UTC; every-seconds is 60 to 2678400; timeout-ms is 1000 to 30000, default 10000)",
|
|
443
|
+
"ohmyhost database schedule set --project ULID --environment dev|prod --name NAME (--cron EXPR | --every-seconds N) --statements-file PATH [--timeout-ms N] [--enabled true|false] --yes --json (runs the statements in the file, a UTF-8 JSON array of 1 to 20 SQL strings, as the runtime role of the application; cron has five fields in UTC; every-seconds is 60 to 2678400; timeout-ms is 1000 to 30000, default 10000). A project whose Stop budget is reached has its schedules disabled automatically, within about an hour of the billed usage reaching the budget: the credit service does this after its hourly pgcf pass, and Continue budgets are never touched. While the budget is reached, schedule set with enabled true and schedule run are refused with project_budget_exceeded (HTTP 402). Re-enabling is manual: raise the budget (or wait for the next UTC month) and run database schedule set --enabled true again with the schedule body (read it with schedule get).",
|
|
438
444
|
"database schedule list":
|
|
439
445
|
"ohmyhost database schedule list --project ULID [--environment dev|prod] --json (dev when omitted)",
|
|
440
446
|
"database schedule get":
|
|
@@ -444,9 +450,9 @@ const HELP_USAGE = Object.freeze({
|
|
|
444
450
|
"database schedule runs":
|
|
445
451
|
"ohmyhost database schedule runs --project ULID [--environment dev|prod] --name NAME [--limit 1..50] --json",
|
|
446
452
|
"database schedule run":
|
|
447
|
-
"ohmyhost database schedule run --project ULID --environment dev|prod --name NAME --yes --json (queues one run now, in addition to the timer)",
|
|
453
|
+
"ohmyhost database schedule run --project ULID --environment dev|prod --name NAME --yes --json (queues one run now, in addition to the timer; refused with project_budget_exceeded (HTTP 402) while the project's Stop budget is reached)",
|
|
448
454
|
"database executions":
|
|
449
|
-
"ohmyhost database executions --project ULID [--environment dev|prod] --from ISO --to ISO --granularity hour|day [--limit 1..100] [--cursor CURSOR] --json (UTC timestamps like 2026-10-30T00:00:00.000Z aligned to the granularity, at most 31 days; counts schedule runs, webhook attempts and events per hour or day;
|
|
455
|
+
"ohmyhost database executions --project ULID [--environment dev|prod] --from ISO --to ISO --granularity hour|day [--limit 1..100] [--cursor CURSOR] --json (UTC timestamps like 2026-10-30T00:00:00.000Z aligned to the granularity, at most 31 days; counts schedule runs, webhook attempts and events per hour or day; these are counters only, executions have no price of their own and the awake compute time of the database is what is billed)",
|
|
450
456
|
"database psql":
|
|
451
457
|
"ohmyhost database psql --project ULID --environment dev|prod [--mode read|write] [--ttl 5m|1h|24h|SECONDS] [--json] (starts local psql with a temporary credential and revokes it on exit)",
|
|
452
458
|
link: "ohmyhost link --project ULID --repository-owner OWNER --repository-name REPOSITORY --idempotency-key KEY --json (uses the workspace GitHub connection and waits for the source-link operation)",
|
|
@@ -1191,6 +1197,12 @@ export class ProductCli {
|
|
|
1191
1197
|
return await this.listDatabaseAccess(command, signal);
|
|
1192
1198
|
if (command.kind === "database-access-revoke")
|
|
1193
1199
|
return await this.revokeDatabaseAccess(command, signal);
|
|
1200
|
+
if (command.kind === "database-watch-create")
|
|
1201
|
+
return await this.createDatabaseWatch(command, signal);
|
|
1202
|
+
if (command.kind === "database-watch-list")
|
|
1203
|
+
return await this.listDatabaseWatches(command, signal);
|
|
1204
|
+
if (command.kind === "database-watch-delete")
|
|
1205
|
+
return await this.deleteDatabaseWatch(command, signal);
|
|
1194
1206
|
if (command.kind === "database-webhook-create")
|
|
1195
1207
|
return await this.createDatabaseWebhook(command, signal);
|
|
1196
1208
|
if (command.kind === "database-webhook-list")
|
|
@@ -1952,6 +1964,51 @@ export class ProductCli {
|
|
|
1952
1964
|
return success("database access revoke", { status: "succeeded", access });
|
|
1953
1965
|
}
|
|
1954
1966
|
|
|
1967
|
+
/** The answer names the event type to subscribe to; the watch already carries the columns and the topic. */
|
|
1968
|
+
private async createDatabaseWatch(
|
|
1969
|
+
command: Extract<ProductCliCommand, { kind: "database-watch-create" }>,
|
|
1970
|
+
signal: AbortSignal,
|
|
1971
|
+
): Promise<CliResult> {
|
|
1972
|
+
const api = await this.authenticatedApi(command.credentialStore, signal);
|
|
1973
|
+
const watch = await api.createProjectDatabaseWatch({
|
|
1974
|
+
projectId: command.projectId,
|
|
1975
|
+
environment: command.environment,
|
|
1976
|
+
idempotencyKey: command.idempotencyKey,
|
|
1977
|
+
request: command.request,
|
|
1978
|
+
});
|
|
1979
|
+
return success("database watch create", {
|
|
1980
|
+
status: "succeeded",
|
|
1981
|
+
watch,
|
|
1982
|
+
next_action: `Run '${this.dependencies.commandPrefix} database webhook create --project ${command.projectId} --environment ${command.environment} --url HTTPS_URL --event-types ${watch.event_type} --idempotency-key KEY --yes --json' to receive ${watch.event_type} events at an HTTPS receiver.`,
|
|
1983
|
+
});
|
|
1984
|
+
}
|
|
1985
|
+
|
|
1986
|
+
private async listDatabaseWatches(
|
|
1987
|
+
command: Extract<ProductCliCommand, { kind: "database-watch-list" }>,
|
|
1988
|
+
signal: AbortSignal,
|
|
1989
|
+
): Promise<CliResult> {
|
|
1990
|
+
const api = await this.authenticatedApi(command.credentialStore, signal);
|
|
1991
|
+
const page = await api.listProjectDatabaseWatches({
|
|
1992
|
+
projectId: command.projectId,
|
|
1993
|
+
environment: command.environment,
|
|
1994
|
+
});
|
|
1995
|
+
return success("database watch list", { status: "succeeded", watch: page.items });
|
|
1996
|
+
}
|
|
1997
|
+
|
|
1998
|
+
private async deleteDatabaseWatch(
|
|
1999
|
+
command: Extract<ProductCliCommand, { kind: "database-watch-delete" }>,
|
|
2000
|
+
signal: AbortSignal,
|
|
2001
|
+
): Promise<CliResult> {
|
|
2002
|
+
const api = await this.authenticatedApi(command.credentialStore, signal);
|
|
2003
|
+
const deleted = await api.deleteProjectDatabaseWatch({
|
|
2004
|
+
projectId: command.projectId,
|
|
2005
|
+
environment: command.environment,
|
|
2006
|
+
idempotencyKey: command.idempotencyKey,
|
|
2007
|
+
watchId: command.watchId,
|
|
2008
|
+
});
|
|
2009
|
+
return success("database watch delete", { status: "succeeded", deleted });
|
|
2010
|
+
}
|
|
2011
|
+
|
|
1955
2012
|
/** The signing secret is returned by create only; every other answer carries no secret. */
|
|
1956
2013
|
private async createDatabaseWebhook(
|
|
1957
2014
|
command: Extract<ProductCliCommand, { kind: "database-webhook-create" }>,
|
|
@@ -3526,6 +3583,9 @@ const parsedCommandName = (command: ProductCliCommand): CommandLabel => {
|
|
|
3526
3583
|
if (command.kind === "database-access-list") return "database access list";
|
|
3527
3584
|
if (command.kind === "database-access-revoke") return "database access revoke";
|
|
3528
3585
|
if (command.kind === "database-psql") return "database psql";
|
|
3586
|
+
if (command.kind === "database-watch-create") return "database watch create";
|
|
3587
|
+
if (command.kind === "database-watch-list") return "database watch list";
|
|
3588
|
+
if (command.kind === "database-watch-delete") return "database watch delete";
|
|
3529
3589
|
if (command.kind === "database-webhook-create") return "database webhook create";
|
|
3530
3590
|
if (command.kind === "database-webhook-list") return "database webhook list";
|
|
3531
3591
|
if (command.kind === "database-webhook-get") return "database webhook get";
|
|
@@ -6,9 +6,12 @@ import {
|
|
|
6
6
|
parseDatabaseListLimit,
|
|
7
7
|
parseDatabaseScheduleName,
|
|
8
8
|
parseDatabaseUsageWindow,
|
|
9
|
+
parseDatabaseWatchCreateRequest,
|
|
10
|
+
parseDatabaseWatchId,
|
|
9
11
|
parseDatabaseWebhookCreateRequest,
|
|
10
12
|
parseDatabaseWebhookId,
|
|
11
|
-
type
|
|
13
|
+
type DatabaseWatchRequest,
|
|
14
|
+
type DatabaseWebhookEventPattern,
|
|
12
15
|
} from "@ohmyhost/contracts/database-events";
|
|
13
16
|
import {
|
|
14
17
|
databaseSizeForMemory,
|
|
@@ -404,12 +407,36 @@ export type ProductCliCommand =
|
|
|
404
407
|
readonly yes: true;
|
|
405
408
|
readonly credentialStore: "native";
|
|
406
409
|
}
|
|
410
|
+
| {
|
|
411
|
+
readonly kind: "database-watch-create";
|
|
412
|
+
readonly projectId: string;
|
|
413
|
+
readonly environment: "dev" | "prod";
|
|
414
|
+
readonly request: DatabaseWatchRequest;
|
|
415
|
+
readonly idempotencyKey: string;
|
|
416
|
+
readonly yes: true;
|
|
417
|
+
readonly credentialStore: "native";
|
|
418
|
+
}
|
|
419
|
+
| {
|
|
420
|
+
readonly kind: "database-watch-list";
|
|
421
|
+
readonly projectId: string;
|
|
422
|
+
readonly environment: "dev" | "prod";
|
|
423
|
+
readonly credentialStore: "native";
|
|
424
|
+
}
|
|
425
|
+
| {
|
|
426
|
+
readonly kind: "database-watch-delete";
|
|
427
|
+
readonly projectId: string;
|
|
428
|
+
readonly environment: "dev" | "prod";
|
|
429
|
+
readonly watchId: string;
|
|
430
|
+
readonly idempotencyKey: string;
|
|
431
|
+
readonly yes: true;
|
|
432
|
+
readonly credentialStore: "native";
|
|
433
|
+
}
|
|
407
434
|
| {
|
|
408
435
|
readonly kind: "database-webhook-create";
|
|
409
436
|
readonly projectId: string;
|
|
410
437
|
readonly environment: "dev" | "prod";
|
|
411
438
|
readonly url: string;
|
|
412
|
-
readonly eventTypes: readonly
|
|
439
|
+
readonly eventTypes: readonly DatabaseWebhookEventPattern[];
|
|
413
440
|
readonly headersFile: string | null;
|
|
414
441
|
readonly idempotencyKey: string;
|
|
415
442
|
readonly yes: true;
|
|
@@ -1003,6 +1030,9 @@ export type RecognizedCommandLabel =
|
|
|
1003
1030
|
| "database access create"
|
|
1004
1031
|
| "database access list"
|
|
1005
1032
|
| "database access revoke"
|
|
1033
|
+
| "database watch create"
|
|
1034
|
+
| "database watch list"
|
|
1035
|
+
| "database watch delete"
|
|
1006
1036
|
| "database webhook create"
|
|
1007
1037
|
| "database webhook list"
|
|
1008
1038
|
| "database webhook get"
|
|
@@ -1174,6 +1204,11 @@ export const recognizedCommandLabel = (argv: readonly string[]): RecognizedComma
|
|
|
1174
1204
|
if (values[1] === "list") return "database access list";
|
|
1175
1205
|
if (values[1] === "revoke") return "database access revoke";
|
|
1176
1206
|
}
|
|
1207
|
+
if (value === "database" && values[0] === "watch") {
|
|
1208
|
+
if (values[1] === "create") return "database watch create";
|
|
1209
|
+
if (values[1] === "list") return "database watch list";
|
|
1210
|
+
if (values[1] === "delete") return "database watch delete";
|
|
1211
|
+
}
|
|
1177
1212
|
if (value === "database" && values[0] === "webhook") {
|
|
1178
1213
|
if (values[1] === "create") return "database webhook create";
|
|
1179
1214
|
if (values[1] === "list") return "database webhook list";
|
|
@@ -2063,6 +2098,92 @@ export const parseProductCliCommand = (argv: readonly string[]): ProductCliComma
|
|
|
2063
2098
|
}
|
|
2064
2099
|
throw new InvalidCommandError();
|
|
2065
2100
|
}
|
|
2101
|
+
if (first === "database" && values[0] === "watch") {
|
|
2102
|
+
values.shift();
|
|
2103
|
+
const subcommand = values.shift();
|
|
2104
|
+
if (subcommand === "create") {
|
|
2105
|
+
if (!yes || wait || follow || revoke || stdin) throw new InvalidCommandError();
|
|
2106
|
+
const options = parseOptionalOptions(values, [
|
|
2107
|
+
"--project",
|
|
2108
|
+
"--environment",
|
|
2109
|
+
"--table",
|
|
2110
|
+
"--schema",
|
|
2111
|
+
"--columns",
|
|
2112
|
+
"--operations",
|
|
2113
|
+
"--idempotency-key",
|
|
2114
|
+
]);
|
|
2115
|
+
const projectId = options["--project"],
|
|
2116
|
+
environment = options["--environment"],
|
|
2117
|
+
table = options["--table"],
|
|
2118
|
+
schema = options["--schema"],
|
|
2119
|
+
columns = options["--columns"],
|
|
2120
|
+
operations = options["--operations"],
|
|
2121
|
+
idempotencyKey = options["--idempotency-key"];
|
|
2122
|
+
if (
|
|
2123
|
+
!isValue(projectId) ||
|
|
2124
|
+
!isValue(idempotencyKey) ||
|
|
2125
|
+
!isValue(table) ||
|
|
2126
|
+
!isValue(columns) ||
|
|
2127
|
+
(environment !== "dev" && environment !== "prod")
|
|
2128
|
+
)
|
|
2129
|
+
throw new InvalidCommandError();
|
|
2130
|
+
const request = contractValue(() =>
|
|
2131
|
+
parseDatabaseWatchCreateRequest({
|
|
2132
|
+
schema,
|
|
2133
|
+
table,
|
|
2134
|
+
columns: columns.split(","),
|
|
2135
|
+
...(operations === undefined ? {} : { operations: operations.split(",") }),
|
|
2136
|
+
}),
|
|
2137
|
+
);
|
|
2138
|
+
return {
|
|
2139
|
+
kind: "database-watch-create",
|
|
2140
|
+
projectId,
|
|
2141
|
+
environment,
|
|
2142
|
+
request,
|
|
2143
|
+
idempotencyKey,
|
|
2144
|
+
yes: true,
|
|
2145
|
+
credentialStore,
|
|
2146
|
+
};
|
|
2147
|
+
}
|
|
2148
|
+
if (subcommand === "list") {
|
|
2149
|
+
if (yes || wait || follow || revoke || stdin) throw new InvalidCommandError();
|
|
2150
|
+
const options = parseOptionalOptions(values, ["--project", "--environment"]);
|
|
2151
|
+
const projectId = options["--project"],
|
|
2152
|
+
environment = options["--environment"] ?? "dev";
|
|
2153
|
+
if (!isValue(projectId) || (environment !== "dev" && environment !== "prod"))
|
|
2154
|
+
throw new InvalidCommandError();
|
|
2155
|
+
return { kind: "database-watch-list", projectId, environment, credentialStore };
|
|
2156
|
+
}
|
|
2157
|
+
if (subcommand === "delete") {
|
|
2158
|
+
if (!yes || wait || follow || revoke || stdin) throw new InvalidCommandError();
|
|
2159
|
+
const options = parseOptionalOptions(values, [
|
|
2160
|
+
"--project",
|
|
2161
|
+
"--environment",
|
|
2162
|
+
"--watch",
|
|
2163
|
+
"--idempotency-key",
|
|
2164
|
+
]);
|
|
2165
|
+
const projectId = options["--project"],
|
|
2166
|
+
environment = options["--environment"],
|
|
2167
|
+
watchId = options["--watch"],
|
|
2168
|
+
idempotencyKey = options["--idempotency-key"];
|
|
2169
|
+
if (
|
|
2170
|
+
!isValue(projectId) ||
|
|
2171
|
+
!isValue(idempotencyKey) ||
|
|
2172
|
+
(environment !== "dev" && environment !== "prod")
|
|
2173
|
+
)
|
|
2174
|
+
throw new InvalidCommandError();
|
|
2175
|
+
return {
|
|
2176
|
+
kind: "database-watch-delete",
|
|
2177
|
+
projectId,
|
|
2178
|
+
environment,
|
|
2179
|
+
watchId: contractValue(() => parseDatabaseWatchId(watchId)),
|
|
2180
|
+
idempotencyKey,
|
|
2181
|
+
yes: true,
|
|
2182
|
+
credentialStore,
|
|
2183
|
+
};
|
|
2184
|
+
}
|
|
2185
|
+
throw new InvalidCommandError();
|
|
2186
|
+
}
|
|
2066
2187
|
if (first === "database" && values[0] === "webhook") {
|
|
2067
2188
|
values.shift();
|
|
2068
2189
|
const subcommand = values.shift();
|
|
@@ -33,6 +33,9 @@ import {
|
|
|
33
33
|
assertDatabaseWebhookDeliveryPage,
|
|
34
34
|
assertDatabaseWebhookPage,
|
|
35
35
|
assertDatabaseWebhookReplayAccepted,
|
|
36
|
+
assertDatabaseWatch,
|
|
37
|
+
assertDatabaseWatchDeleted,
|
|
38
|
+
assertDatabaseWatchPage,
|
|
36
39
|
assertDatabaseWebhookTest,
|
|
37
40
|
type DatabaseExecutionUsagePage,
|
|
38
41
|
type DatabaseSchedule,
|
|
@@ -45,7 +48,11 @@ import {
|
|
|
45
48
|
type DatabaseWebhookCreated,
|
|
46
49
|
type DatabaseWebhookDeleted,
|
|
47
50
|
type DatabaseWebhookDeliveryPage,
|
|
48
|
-
type
|
|
51
|
+
type DatabaseWatch,
|
|
52
|
+
type DatabaseWatchDeleted,
|
|
53
|
+
type DatabaseWatchPage,
|
|
54
|
+
type DatabaseWatchRequest,
|
|
55
|
+
type DatabaseWebhookEventPattern,
|
|
49
56
|
type DatabaseWebhookPage,
|
|
50
57
|
type DatabaseWebhookReplayAccepted,
|
|
51
58
|
type DatabaseWebhookTestResult,
|
|
@@ -152,6 +159,9 @@ import {
|
|
|
152
159
|
getProjectDatabaseWebhook,
|
|
153
160
|
deleteProjectDatabaseWebhook,
|
|
154
161
|
testProjectDatabaseWebhook,
|
|
162
|
+
createProjectDatabaseWatch,
|
|
163
|
+
listProjectDatabaseWatches,
|
|
164
|
+
deleteProjectDatabaseWatch,
|
|
155
165
|
listProjectDatabaseWebhookDeliveries,
|
|
156
166
|
replayProjectDatabaseWebhookDelivery,
|
|
157
167
|
setProjectDatabaseSchedule,
|
|
@@ -328,7 +338,7 @@ export interface ProductApi {
|
|
|
328
338
|
readonly environment: "dev" | "prod";
|
|
329
339
|
readonly idempotencyKey: string;
|
|
330
340
|
readonly url: string;
|
|
331
|
-
readonly eventTypes: readonly
|
|
341
|
+
readonly eventTypes: readonly DatabaseWebhookEventPattern[];
|
|
332
342
|
readonly headers: Readonly<Record<string, string>>;
|
|
333
343
|
}): Promise<DatabaseWebhookCreated>;
|
|
334
344
|
listProjectDatabaseWebhooks(input: {
|
|
@@ -350,6 +360,22 @@ export interface ProductApi {
|
|
|
350
360
|
readonly environment: "dev" | "prod";
|
|
351
361
|
readonly webhookId: string;
|
|
352
362
|
}): Promise<DatabaseWebhookTestResult>;
|
|
363
|
+
createProjectDatabaseWatch(input: {
|
|
364
|
+
readonly projectId: string;
|
|
365
|
+
readonly environment: "dev" | "prod";
|
|
366
|
+
readonly idempotencyKey: string;
|
|
367
|
+
readonly request: DatabaseWatchRequest;
|
|
368
|
+
}): Promise<DatabaseWatch>;
|
|
369
|
+
listProjectDatabaseWatches(input: {
|
|
370
|
+
readonly projectId: string;
|
|
371
|
+
readonly environment: "dev" | "prod";
|
|
372
|
+
}): Promise<DatabaseWatchPage>;
|
|
373
|
+
deleteProjectDatabaseWatch(input: {
|
|
374
|
+
readonly projectId: string;
|
|
375
|
+
readonly environment: "dev" | "prod";
|
|
376
|
+
readonly idempotencyKey: string;
|
|
377
|
+
readonly watchId: string;
|
|
378
|
+
}): Promise<DatabaseWatchDeleted>;
|
|
353
379
|
listProjectDatabaseWebhookDeliveries(input: {
|
|
354
380
|
readonly projectId: string;
|
|
355
381
|
readonly environment: "dev" | "prod";
|
|
@@ -566,6 +592,7 @@ export interface ProductApi {
|
|
|
566
592
|
|
|
567
593
|
/** A webhook answer that names another environment, webhook or delivery than the request did. */
|
|
568
594
|
const WEBHOOK_SCOPE_MISMATCH = "Webhook response scope mismatch";
|
|
595
|
+
const WATCH_SCOPE_MISMATCH = "Watch response scope mismatch";
|
|
569
596
|
/** A schedule answer that names another environment or schedule than the request did. */
|
|
570
597
|
const SCHEDULE_SCOPE_MISMATCH = "Schedule response scope mismatch";
|
|
571
598
|
|
|
@@ -889,6 +916,63 @@ export class GeneratedSdkProductApi implements ProductApi {
|
|
|
889
916
|
return value;
|
|
890
917
|
}
|
|
891
918
|
|
|
919
|
+
public async createProjectDatabaseWatch(
|
|
920
|
+
input: Parameters<ProductApi["createProjectDatabaseWatch"]>[0],
|
|
921
|
+
): Promise<DatabaseWatch> {
|
|
922
|
+
const value = await createProjectDatabaseWatch(
|
|
923
|
+
{
|
|
924
|
+
project_id: input.projectId,
|
|
925
|
+
"Idempotency-Key": input.idempotencyKey,
|
|
926
|
+
databaseWatchCreateRequest: {
|
|
927
|
+
environment: input.environment,
|
|
928
|
+
schema: input.request.schema,
|
|
929
|
+
table: input.request.table,
|
|
930
|
+
columns: [...input.request.columns],
|
|
931
|
+
operations: [...input.request.operations],
|
|
932
|
+
},
|
|
933
|
+
},
|
|
934
|
+
{ client: this.#client },
|
|
935
|
+
);
|
|
936
|
+
assertDatabaseWatch(value);
|
|
937
|
+
if (
|
|
938
|
+
value.environment !== input.environment ||
|
|
939
|
+
value.schema !== input.request.schema ||
|
|
940
|
+
value.table !== input.request.table
|
|
941
|
+
)
|
|
942
|
+
throw new TypeError(WATCH_SCOPE_MISMATCH);
|
|
943
|
+
return value;
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
public async listProjectDatabaseWatches(
|
|
947
|
+
input: Parameters<ProductApi["listProjectDatabaseWatches"]>[0],
|
|
948
|
+
): Promise<DatabaseWatchPage> {
|
|
949
|
+
const value = await listProjectDatabaseWatches(
|
|
950
|
+
{ project_id: input.projectId, environment: input.environment },
|
|
951
|
+
{ client: this.#client },
|
|
952
|
+
);
|
|
953
|
+
assertDatabaseWatchPage(value);
|
|
954
|
+
if (value.items.some((item) => item.environment !== input.environment))
|
|
955
|
+
throw new TypeError(WATCH_SCOPE_MISMATCH);
|
|
956
|
+
return value;
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
public async deleteProjectDatabaseWatch(
|
|
960
|
+
input: Parameters<ProductApi["deleteProjectDatabaseWatch"]>[0],
|
|
961
|
+
): Promise<DatabaseWatchDeleted> {
|
|
962
|
+
const value = await deleteProjectDatabaseWatch(
|
|
963
|
+
{
|
|
964
|
+
project_id: input.projectId,
|
|
965
|
+
environment: input.environment,
|
|
966
|
+
"Idempotency-Key": input.idempotencyKey,
|
|
967
|
+
watch_id: input.watchId,
|
|
968
|
+
},
|
|
969
|
+
{ client: this.#client },
|
|
970
|
+
);
|
|
971
|
+
assertDatabaseWatchDeleted(value);
|
|
972
|
+
if (value.id !== input.watchId) throw new TypeError(WATCH_SCOPE_MISMATCH);
|
|
973
|
+
return value;
|
|
974
|
+
}
|
|
975
|
+
|
|
892
976
|
/** The signing secret exists only in this answer; the CLI prints it once and stores nothing. */
|
|
893
977
|
public async createProjectDatabaseWebhook(
|
|
894
978
|
input: Parameters<ProductApi["createProjectDatabaseWebhook"]>[0],
|