@amerged/ohmyhost-cli 0.1.44 → 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-VJWPDFZ5.js → chunk-C6KEAOJP.js} +498 -7
- 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 +61 -1
- 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/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 +150 -0
- package/src/packages/sdk-ts/src/generated/types.gen.ts +266 -4
|
@@ -40219,6 +40219,36 @@ var PROBLEM_POLICY = {
|
|
|
40219
40219
|
action: "The platform is still retrying this webhook delivery. Read the delivery in the delivery list; replay it only if it ends dead_lettered or the receiver needs the event again.",
|
|
40220
40220
|
title: "Webhook delivery still pending"
|
|
40221
40221
|
},
|
|
40222
|
+
database_watch_limit: {
|
|
40223
|
+
status: 409,
|
|
40224
|
+
retryable: false,
|
|
40225
|
+
action: "List the project's database watches for this environment and delete one you no longer need, then create the watch again.",
|
|
40226
|
+
title: "Database watch limit reached"
|
|
40227
|
+
},
|
|
40228
|
+
database_watch_table_unavailable: {
|
|
40229
|
+
status: 409,
|
|
40230
|
+
retryable: false,
|
|
40231
|
+
action: "The table must exist as an ordinary table owned by the application, created by a deployed migration; views, partitions, temporary tables and the schemas pgcf, ohmyhost, information_schema and pg_* cannot be watched. Fix the name or deploy the migration, then create the watch again.",
|
|
40232
|
+
title: "Table cannot be watched"
|
|
40233
|
+
},
|
|
40234
|
+
database_watch_column_unavailable: {
|
|
40235
|
+
status: 409,
|
|
40236
|
+
retryable: false,
|
|
40237
|
+
action: "List only existing column names exactly as written, names are case-sensitive. Delete the watch before a migration drops a published column, because the write would fail.",
|
|
40238
|
+
title: "Watched column does not exist"
|
|
40239
|
+
},
|
|
40240
|
+
database_watch_events_unavailable: {
|
|
40241
|
+
status: 409,
|
|
40242
|
+
retryable: false,
|
|
40243
|
+
action: "The platform event schema is installed when the database wakes: run any query against that environment, wait for the answer, then create the watch again. If it still fails, report the request_id through feedback.",
|
|
40244
|
+
title: "Database events not installed yet"
|
|
40245
|
+
},
|
|
40246
|
+
database_watch_conflict: {
|
|
40247
|
+
status: 409,
|
|
40248
|
+
retryable: false,
|
|
40249
|
+
action: "A migration already attaches a capture trigger to this table: keep it and skip the watch, or remove it from the migrations, deploy and create the watch again. A table carries one capture trigger.",
|
|
40250
|
+
title: "Table already has a capture trigger"
|
|
40251
|
+
},
|
|
40222
40252
|
project_notes_conflict: {
|
|
40223
40253
|
status: 409,
|
|
40224
40254
|
retryable: false,
|
|
@@ -40483,7 +40513,7 @@ var PROBLEM_POLICY = {
|
|
|
40483
40513
|
api_key_permissions_unavailable: {
|
|
40484
40514
|
status: 503,
|
|
40485
40515
|
retryable: false,
|
|
40486
|
-
action: "Report the platform user-key permission configuration through feedback. Repeated login
|
|
40516
|
+
action: "Report the platform user-key permission configuration through feedback with this request_id; it affects every token the same way, whatever the integration. Repeated login does not fix it. After the platform confirms the fix, repeat the same create with the same name and Idempotency-Key.",
|
|
40487
40517
|
title: "Token permissions unavailable"
|
|
40488
40518
|
},
|
|
40489
40519
|
reconciliation_exhausted: {
|
|
@@ -42389,6 +42419,9 @@ var DATABASE_WEBHOOK_EVENT_TYPES = [
|
|
|
42389
42419
|
"database.resized",
|
|
42390
42420
|
"database.deleted"
|
|
42391
42421
|
];
|
|
42422
|
+
var DATABASE_WATCH_OPERATIONS = ["insert", "update", "delete"];
|
|
42423
|
+
var DATABASE_WATCH_MAX_COLUMNS = 32;
|
|
42424
|
+
var DATABASE_WATCH_DEFAULT_SCHEMA = "public";
|
|
42392
42425
|
var DATABASE_WEBHOOK_MAX_EVENT_TYPES = 16;
|
|
42393
42426
|
var DATABASE_WEBHOOK_MAX_HEADERS = 8;
|
|
42394
42427
|
var DATABASE_WEBHOOK_URL_MAX_LENGTH = 2048;
|
|
@@ -42432,7 +42465,22 @@ var USAGE_MAX_RANGE_MS = 31 * 24 * USAGE_HOUR_MS;
|
|
|
42432
42465
|
var WEBHOOK_KEYS = ["id", "environment", "url", "event_types", "header_names", "created_at"];
|
|
42433
42466
|
var WEBHOOK_ID_PATTERN = /^whk_[a-z0-9]{20}$/u;
|
|
42434
42467
|
var DELIVERY_ID_PATTERN = /^dlv_[0-9a-f]{20}$/u;
|
|
42435
|
-
var EVENT_ID_PATTERN = /^evt_[0-9a-f]{20}$/u;
|
|
42468
|
+
var EVENT_ID_PATTERN = /^(?:evt_[0-9a-f]{20}|[a-z][a-z0-9]{19}:[1-9][0-9]{0,15}:[1-9][0-9]{0,15})$/u;
|
|
42469
|
+
var DATA_SUBSCRIPTION_PATTERN = /^data\.(?:\*|[a-z][a-z0-9_]{0,47})$/u;
|
|
42470
|
+
var DATA_EVENT_TYPE_PATTERN = /^data\.[a-z][a-z0-9_]{0,47}$/u;
|
|
42471
|
+
var DATABASE_WATCH_ID_PATTERN = /^pgcf_watch_[0-9a-f]{8}$/u;
|
|
42472
|
+
var DATABASE_WATCH_IDENTIFIER_PATTERN = /^[A-Za-z_][A-Za-z0-9_]{0,62}$/u;
|
|
42473
|
+
var DATABASE_WATCH_FORBIDDEN_SCHEMAS = ["information_schema", "pgcf", "ohmyhost"];
|
|
42474
|
+
var DATABASE_WATCH_KEYS = [
|
|
42475
|
+
"id",
|
|
42476
|
+
"environment",
|
|
42477
|
+
"schema",
|
|
42478
|
+
"table",
|
|
42479
|
+
"columns",
|
|
42480
|
+
"operations",
|
|
42481
|
+
"topic",
|
|
42482
|
+
"event_type"
|
|
42483
|
+
];
|
|
42436
42484
|
var SCHEDULE_NAME_PATTERN = /^[a-z][a-z0-9_-]{0,62}$/u;
|
|
42437
42485
|
var CURSOR_PATTERN = /^[A-Za-z0-9._|:=+/-]{1,200}$/u;
|
|
42438
42486
|
var HEADER_NAME_PATTERN = /^[A-Za-z][A-Za-z0-9-]{0,63}$/u;
|
|
@@ -42454,11 +42502,53 @@ function parseDatabaseWebhookId(value) {
|
|
|
42454
42502
|
throw new TypeError("Invalid database webhook id");
|
|
42455
42503
|
return value;
|
|
42456
42504
|
}
|
|
42505
|
+
function parseDatabaseWatchId(value) {
|
|
42506
|
+
if (!isDatabaseWatchTriggerName(value))
|
|
42507
|
+
throw new TypeError("Invalid database watch id");
|
|
42508
|
+
return value;
|
|
42509
|
+
}
|
|
42457
42510
|
function parseDatabaseDeliveryId(value) {
|
|
42458
42511
|
if (!matches(value, DELIVERY_ID_PATTERN))
|
|
42459
42512
|
throw new TypeError("Invalid database delivery id");
|
|
42460
42513
|
return value;
|
|
42461
42514
|
}
|
|
42515
|
+
function isDatabaseWatchTriggerName(value) {
|
|
42516
|
+
return matches(value, DATABASE_WATCH_ID_PATTERN);
|
|
42517
|
+
}
|
|
42518
|
+
function isDatabaseWatchIdentifier(value) {
|
|
42519
|
+
return matches(value, DATABASE_WATCH_IDENTIFIER_PATTERN);
|
|
42520
|
+
}
|
|
42521
|
+
function isDatabaseWatchSchema(value) {
|
|
42522
|
+
if (!isDatabaseWatchIdentifier(value))
|
|
42523
|
+
return false;
|
|
42524
|
+
const lower = value.toLowerCase();
|
|
42525
|
+
return !lower.startsWith("pg_") && !DATABASE_WATCH_FORBIDDEN_SCHEMAS.includes(lower);
|
|
42526
|
+
}
|
|
42527
|
+
function dataEventTopic(tableName) {
|
|
42528
|
+
const mapped = Array.from(tableName, (character) => {
|
|
42529
|
+
const lower = Array.from(character.toLowerCase())[0] ?? "_";
|
|
42530
|
+
return /^[a-z0-9_]$/u.test(lower) ? lower : "_";
|
|
42531
|
+
}).join("");
|
|
42532
|
+
const topic = /^[a-z]/u.test(mapped) ? mapped : `t_${mapped}`;
|
|
42533
|
+
return topic.slice(0, 48);
|
|
42534
|
+
}
|
|
42535
|
+
function parseDatabaseWatchCreateRequest(value) {
|
|
42536
|
+
if (!record2(value) || !onlyKeys(value, ["schema", "table", "columns", "operations"]) || !isDatabaseWatchIdentifier(value["table"]) || !Array.isArray(value["columns"]) || value["columns"].length < 1 || value["columns"].length > DATABASE_WATCH_MAX_COLUMNS || !value["columns"].every(isDatabaseWatchIdentifier) || new Set(value["columns"]).size !== value["columns"].length)
|
|
42537
|
+
throw new TypeError("Invalid database watch request");
|
|
42538
|
+
return {
|
|
42539
|
+
...parseDatabaseWatchTarget({ schema: value["schema"], table: value["table"] }),
|
|
42540
|
+
columns: value["columns"],
|
|
42541
|
+
operations: parseWatchOperations(value["operations"])
|
|
42542
|
+
};
|
|
42543
|
+
}
|
|
42544
|
+
function parseDatabaseWatchTarget(value) {
|
|
42545
|
+
if (!record2(value) || !onlyKeys(value, ["schema", "table"]) || !isDatabaseWatchIdentifier(value["table"]))
|
|
42546
|
+
throw new TypeError("Invalid database watch target");
|
|
42547
|
+
const schema = value["schema"] === void 0 ? DATABASE_WATCH_DEFAULT_SCHEMA : value["schema"];
|
|
42548
|
+
if (!isDatabaseWatchSchema(schema))
|
|
42549
|
+
throw new TypeError("Invalid database watch target");
|
|
42550
|
+
return { schema, table: value["table"] };
|
|
42551
|
+
}
|
|
42462
42552
|
function parseDatabaseScheduleName(value) {
|
|
42463
42553
|
if (!matches(value, SCHEDULE_NAME_PATTERN))
|
|
42464
42554
|
throw new TypeError("Invalid database schedule name");
|
|
@@ -42515,6 +42605,20 @@ function assertDatabaseWebhook(value) {
|
|
|
42515
42605
|
throw new TypeError("Invalid database webhook");
|
|
42516
42606
|
assertWebhookFields(value);
|
|
42517
42607
|
}
|
|
42608
|
+
function assertDatabaseWatch(value) {
|
|
42609
|
+
if (!record2(value) || !exact2(value, DATABASE_WATCH_KEYS) || !matches(value["id"], DATABASE_WATCH_ID_PATTERN) || !oneOf(["dev", "prod"], value["environment"]) || !isDatabaseWatchSchema(value["schema"]) || !isDatabaseWatchIdentifier(value["table"]) || !Array.isArray(value["columns"]) || value["columns"].length < 1 || value["columns"].length > DATABASE_WATCH_MAX_COLUMNS || !value["columns"].every(isDatabaseWatchIdentifier) || !isCanonicalOperations(value["operations"]) || value["topic"] !== dataEventTopic(value["table"]) || value["event_type"] !== `data.${value["topic"]}`)
|
|
42610
|
+
throw new TypeError("Invalid database watch");
|
|
42611
|
+
}
|
|
42612
|
+
function assertDatabaseWatchPage(value) {
|
|
42613
|
+
if (!record2(value) || !exact2(value, ["items"]) || !pageItems(value["items"]))
|
|
42614
|
+
throw new TypeError("Invalid database watch page");
|
|
42615
|
+
for (const item of value["items"])
|
|
42616
|
+
assertDatabaseWatch(item);
|
|
42617
|
+
}
|
|
42618
|
+
function assertDatabaseWatchDeleted(value) {
|
|
42619
|
+
if (!record2(value) || !exact2(value, ["id", "deleted"]) || !matches(value["id"], DATABASE_WATCH_ID_PATTERN) || value["deleted"] !== true)
|
|
42620
|
+
throw new TypeError("Invalid database watch deletion");
|
|
42621
|
+
}
|
|
42518
42622
|
function assertDatabaseWebhookCreated(value) {
|
|
42519
42623
|
if (!record2(value) || !exact2(value, [...WEBHOOK_KEYS, "secret"]) || typeof value["secret"] !== "string" || value["secret"].length === 0)
|
|
42520
42624
|
throw new TypeError("Invalid database webhook");
|
|
@@ -42543,7 +42647,7 @@ function assertDatabaseWebhookDelivery(value) {
|
|
|
42543
42647
|
"delivered_at",
|
|
42544
42648
|
"last_status",
|
|
42545
42649
|
"last_error"
|
|
42546
|
-
]) || !matches(value["id"], DELIVERY_ID_PATTERN) || !matches(value["event_id"], EVENT_ID_PATTERN) || !
|
|
42650
|
+
]) || !matches(value["id"], DELIVERY_ID_PATTERN) || !matches(value["event_id"], EVENT_ID_PATTERN) || !isDeliveredEventType(value["event_type"]) || !matches(value["webhook_id"], WEBHOOK_ID_PATTERN) || !oneOf(["pending", "delivered", "dead_lettered"], value["state"]) || !nonNegativeInteger(value["attempts"]) || !timestamp2(value["created_at"]) || !nullable(value["next_attempt_at"], timestamp2) || !nullable(value["delivered_at"], timestamp2) || !nullable(value["last_status"], Number.isSafeInteger) || !nullable(value["last_error"], (error) => oneOf(["timeout", "network", "http", "expired", "permanent"], error)))
|
|
42547
42651
|
throw new TypeError("Invalid database webhook delivery");
|
|
42548
42652
|
}
|
|
42549
42653
|
function assertDatabaseWebhookDeliveryPage(value) {
|
|
@@ -42626,7 +42730,7 @@ function assertUsageRow(value) {
|
|
|
42626
42730
|
throw new TypeError("Invalid database execution usage row");
|
|
42627
42731
|
}
|
|
42628
42732
|
function assertWebhookFields(value) {
|
|
42629
|
-
if (!matches(value["id"], WEBHOOK_ID_PATTERN) || !oneOf(["dev", "prod"], value["environment"]) || !isHttpsUrl2(value["url"]) || !Array.isArray(value["event_types"]) || value["event_types"].length < 1 || value["event_types"].length > DATABASE_WEBHOOK_MAX_EVENT_TYPES || !value["event_types"].every(
|
|
42733
|
+
if (!matches(value["id"], WEBHOOK_ID_PATTERN) || !oneOf(["dev", "prod"], value["environment"]) || !isHttpsUrl2(value["url"]) || !Array.isArray(value["event_types"]) || value["event_types"].length < 1 || value["event_types"].length > DATABASE_WEBHOOK_MAX_EVENT_TYPES || !value["event_types"].every(isDatabaseWebhookEventPattern) || !Array.isArray(value["header_names"]) || value["header_names"].length > DATABASE_WEBHOOK_MAX_HEADERS || !value["header_names"].every((name) => matches(name, HEADER_NAME_PATTERN)) || !timestamp2(value["created_at"]))
|
|
42630
42734
|
throw new TypeError("Invalid database webhook");
|
|
42631
42735
|
}
|
|
42632
42736
|
function parseHttpsUrl(value) {
|
|
@@ -42643,11 +42747,33 @@ function isHttpsUrl2(value) {
|
|
|
42643
42747
|
return false;
|
|
42644
42748
|
}
|
|
42645
42749
|
}
|
|
42750
|
+
function isDatabaseWebhookEventPattern(value) {
|
|
42751
|
+
return oneOf(DATABASE_WEBHOOK_EVENT_TYPES, value) || matches(value, DATA_SUBSCRIPTION_PATTERN);
|
|
42752
|
+
}
|
|
42753
|
+
function isDeliveredEventType(value) {
|
|
42754
|
+
return oneOf(DATABASE_WEBHOOK_EVENT_TYPES, value) || matches(value, DATA_EVENT_TYPE_PATTERN);
|
|
42755
|
+
}
|
|
42756
|
+
function isDatabaseWebhookEventTypes(value) {
|
|
42757
|
+
return Array.isArray(value) && value.length >= 1 && value.length <= DATABASE_WEBHOOK_MAX_EVENT_TYPES && value.every(isDatabaseWebhookEventPattern) && new Set(value).size === value.length;
|
|
42758
|
+
}
|
|
42646
42759
|
function parseEventTypes(value) {
|
|
42647
|
-
if (!
|
|
42760
|
+
if (!isDatabaseWebhookEventTypes(value))
|
|
42648
42761
|
throw new TypeError("Invalid database webhook event types");
|
|
42649
42762
|
return value;
|
|
42650
42763
|
}
|
|
42764
|
+
function parseWatchOperations(value) {
|
|
42765
|
+
if (value === void 0)
|
|
42766
|
+
return DATABASE_WATCH_OPERATIONS;
|
|
42767
|
+
if (!Array.isArray(value) || value.length < 1 || !value.every((operation) => oneOf(DATABASE_WATCH_OPERATIONS, operation)) || new Set(value).size !== value.length)
|
|
42768
|
+
throw new TypeError("Invalid database watch request");
|
|
42769
|
+
return DATABASE_WATCH_OPERATIONS.filter((operation) => value.includes(operation));
|
|
42770
|
+
}
|
|
42771
|
+
function isCanonicalOperations(value) {
|
|
42772
|
+
if (!Array.isArray(value) || value.length < 1)
|
|
42773
|
+
return false;
|
|
42774
|
+
const canonical = DATABASE_WATCH_OPERATIONS.filter((operation) => value.includes(operation));
|
|
42775
|
+
return canonical.length === value.length && canonical.every((op, index) => op === value[index]);
|
|
42776
|
+
}
|
|
42651
42777
|
function parseHeaders(value) {
|
|
42652
42778
|
if (!record2(value) || Object.keys(value).length > DATABASE_WEBHOOK_MAX_HEADERS || new Set(Object.keys(value).map((name) => name.toLowerCase())).size !== Object.keys(value).length)
|
|
42653
42779
|
throw new TypeError("Invalid database webhook headers");
|
|
@@ -43083,6 +43209,14 @@ var recognizedCommandLabel = (argv) => {
|
|
|
43083
43209
|
if (values[1] === "revoke")
|
|
43084
43210
|
return "database access revoke";
|
|
43085
43211
|
}
|
|
43212
|
+
if (value === "database" && values[0] === "watch") {
|
|
43213
|
+
if (values[1] === "create")
|
|
43214
|
+
return "database watch create";
|
|
43215
|
+
if (values[1] === "list")
|
|
43216
|
+
return "database watch list";
|
|
43217
|
+
if (values[1] === "delete")
|
|
43218
|
+
return "database watch delete";
|
|
43219
|
+
}
|
|
43086
43220
|
if (value === "database" && values[0] === "webhook") {
|
|
43087
43221
|
if (values[1] === "create")
|
|
43088
43222
|
return "database webhook create";
|
|
@@ -43932,6 +44066,73 @@ var parseProductCliCommand = (argv) => {
|
|
|
43932
44066
|
}
|
|
43933
44067
|
throw new InvalidCommandError();
|
|
43934
44068
|
}
|
|
44069
|
+
if (first === "database" && values[0] === "watch") {
|
|
44070
|
+
values.shift();
|
|
44071
|
+
const subcommand = values.shift();
|
|
44072
|
+
if (subcommand === "create") {
|
|
44073
|
+
if (!yes || wait || follow || revoke || stdin)
|
|
44074
|
+
throw new InvalidCommandError();
|
|
44075
|
+
const options = parseOptionalOptions(values, [
|
|
44076
|
+
"--project",
|
|
44077
|
+
"--environment",
|
|
44078
|
+
"--table",
|
|
44079
|
+
"--schema",
|
|
44080
|
+
"--columns",
|
|
44081
|
+
"--operations",
|
|
44082
|
+
"--idempotency-key"
|
|
44083
|
+
]);
|
|
44084
|
+
const projectId = options["--project"], environment = options["--environment"], table = options["--table"], schema = options["--schema"], columns = options["--columns"], operations = options["--operations"], idempotencyKey = options["--idempotency-key"];
|
|
44085
|
+
if (!isValue(projectId) || !isValue(idempotencyKey) || !isValue(table) || !isValue(columns) || environment !== "dev" && environment !== "prod")
|
|
44086
|
+
throw new InvalidCommandError();
|
|
44087
|
+
const request = contractValue(() => parseDatabaseWatchCreateRequest({
|
|
44088
|
+
schema,
|
|
44089
|
+
table,
|
|
44090
|
+
columns: columns.split(","),
|
|
44091
|
+
...operations === void 0 ? {} : { operations: operations.split(",") }
|
|
44092
|
+
}));
|
|
44093
|
+
return {
|
|
44094
|
+
kind: "database-watch-create",
|
|
44095
|
+
projectId,
|
|
44096
|
+
environment,
|
|
44097
|
+
request,
|
|
44098
|
+
idempotencyKey,
|
|
44099
|
+
yes: true,
|
|
44100
|
+
credentialStore
|
|
44101
|
+
};
|
|
44102
|
+
}
|
|
44103
|
+
if (subcommand === "list") {
|
|
44104
|
+
if (yes || wait || follow || revoke || stdin)
|
|
44105
|
+
throw new InvalidCommandError();
|
|
44106
|
+
const options = parseOptionalOptions(values, ["--project", "--environment"]);
|
|
44107
|
+
const projectId = options["--project"], environment = options["--environment"] ?? "dev";
|
|
44108
|
+
if (!isValue(projectId) || environment !== "dev" && environment !== "prod")
|
|
44109
|
+
throw new InvalidCommandError();
|
|
44110
|
+
return { kind: "database-watch-list", projectId, environment, credentialStore };
|
|
44111
|
+
}
|
|
44112
|
+
if (subcommand === "delete") {
|
|
44113
|
+
if (!yes || wait || follow || revoke || stdin)
|
|
44114
|
+
throw new InvalidCommandError();
|
|
44115
|
+
const options = parseOptionalOptions(values, [
|
|
44116
|
+
"--project",
|
|
44117
|
+
"--environment",
|
|
44118
|
+
"--watch",
|
|
44119
|
+
"--idempotency-key"
|
|
44120
|
+
]);
|
|
44121
|
+
const projectId = options["--project"], environment = options["--environment"], watchId = options["--watch"], idempotencyKey = options["--idempotency-key"];
|
|
44122
|
+
if (!isValue(projectId) || !isValue(idempotencyKey) || environment !== "dev" && environment !== "prod")
|
|
44123
|
+
throw new InvalidCommandError();
|
|
44124
|
+
return {
|
|
44125
|
+
kind: "database-watch-delete",
|
|
44126
|
+
projectId,
|
|
44127
|
+
environment,
|
|
44128
|
+
watchId: contractValue(() => parseDatabaseWatchId(watchId)),
|
|
44129
|
+
idempotencyKey,
|
|
44130
|
+
yes: true,
|
|
44131
|
+
credentialStore
|
|
44132
|
+
};
|
|
44133
|
+
}
|
|
44134
|
+
throw new InvalidCommandError();
|
|
44135
|
+
}
|
|
43935
44136
|
if (first === "database" && values[0] === "webhook") {
|
|
43936
44137
|
values.shift();
|
|
43937
44138
|
const subcommand = values.shift();
|
|
@@ -45317,7 +45518,7 @@ function exact4(v, keys) {
|
|
|
45317
45518
|
// apps/product-cli/package.json
|
|
45318
45519
|
var package_default = {
|
|
45319
45520
|
name: "@ohmyhost/product-cli",
|
|
45320
|
-
version: "0.1.
|
|
45521
|
+
version: "0.1.45",
|
|
45321
45522
|
private: true,
|
|
45322
45523
|
ohmyhost: {
|
|
45323
45524
|
deployment: "production",
|
|
@@ -45662,7 +45863,10 @@ var HELP_USAGE = Object.freeze({
|
|
|
45662
45863
|
"database access create": "ohmyhost database access create --project ULID --environment dev|prod [--mode read|write] [--ttl 5m|1h|24h|SECONDS] [--label TEXT] --yes --json\n The connection URI is shown once. Use it immediately, never store it in files, notes or source, and revoke it when finished.",
|
|
45663
45864
|
"database access list": "ohmyhost database access list --project ULID [--environment dev|prod] --json",
|
|
45664
45865
|
"database access revoke": "ohmyhost database access revoke --project ULID --access ULID --yes --json",
|
|
45665
|
-
"database
|
|
45866
|
+
"database watch create": "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>')",
|
|
45867
|
+
"database watch list": "ohmyhost database watch list --project ULID [--environment dev|prod] --json (dev when omitted; a sleeping database wakes)",
|
|
45868
|
+
"database watch delete": "ohmyhost database watch delete --project ULID --environment dev|prod --watch ID --idempotency-key KEY --yes --json",
|
|
45869
|
+
"database webhook create": "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)",
|
|
45666
45870
|
"database webhook list": "ohmyhost database webhook list --project ULID [--environment dev|prod] --json (dev when omitted; the secret is never listed)",
|
|
45667
45871
|
"database webhook get": "ohmyhost database webhook get --project ULID [--environment dev|prod] --webhook ID --json",
|
|
45668
45872
|
"database webhook delete": "ohmyhost database webhook delete --project ULID --environment dev|prod --webhook ID --yes --json",
|
|
@@ -46153,6 +46357,12 @@ var ProductCli = class {
|
|
|
46153
46357
|
return await this.listDatabaseAccess(command, signal);
|
|
46154
46358
|
if (command.kind === "database-access-revoke")
|
|
46155
46359
|
return await this.revokeDatabaseAccess(command, signal);
|
|
46360
|
+
if (command.kind === "database-watch-create")
|
|
46361
|
+
return await this.createDatabaseWatch(command, signal);
|
|
46362
|
+
if (command.kind === "database-watch-list")
|
|
46363
|
+
return await this.listDatabaseWatches(command, signal);
|
|
46364
|
+
if (command.kind === "database-watch-delete")
|
|
46365
|
+
return await this.deleteDatabaseWatch(command, signal);
|
|
46156
46366
|
if (command.kind === "database-webhook-create")
|
|
46157
46367
|
return await this.createDatabaseWebhook(command, signal);
|
|
46158
46368
|
if (command.kind === "database-webhook-list")
|
|
@@ -46684,6 +46894,39 @@ var ProductCli = class {
|
|
|
46684
46894
|
assertProjectDatabaseAccess(access);
|
|
46685
46895
|
return success("database access revoke", { status: "succeeded", access });
|
|
46686
46896
|
}
|
|
46897
|
+
/** The answer names the event type to subscribe to; the watch already carries the columns and the topic. */
|
|
46898
|
+
async createDatabaseWatch(command, signal) {
|
|
46899
|
+
const api = await this.authenticatedApi(command.credentialStore, signal);
|
|
46900
|
+
const watch = await api.createProjectDatabaseWatch({
|
|
46901
|
+
projectId: command.projectId,
|
|
46902
|
+
environment: command.environment,
|
|
46903
|
+
idempotencyKey: command.idempotencyKey,
|
|
46904
|
+
request: command.request
|
|
46905
|
+
});
|
|
46906
|
+
return success("database watch create", {
|
|
46907
|
+
status: "succeeded",
|
|
46908
|
+
watch,
|
|
46909
|
+
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.`
|
|
46910
|
+
});
|
|
46911
|
+
}
|
|
46912
|
+
async listDatabaseWatches(command, signal) {
|
|
46913
|
+
const api = await this.authenticatedApi(command.credentialStore, signal);
|
|
46914
|
+
const page = await api.listProjectDatabaseWatches({
|
|
46915
|
+
projectId: command.projectId,
|
|
46916
|
+
environment: command.environment
|
|
46917
|
+
});
|
|
46918
|
+
return success("database watch list", { status: "succeeded", watch: page.items });
|
|
46919
|
+
}
|
|
46920
|
+
async deleteDatabaseWatch(command, signal) {
|
|
46921
|
+
const api = await this.authenticatedApi(command.credentialStore, signal);
|
|
46922
|
+
const deleted = await api.deleteProjectDatabaseWatch({
|
|
46923
|
+
projectId: command.projectId,
|
|
46924
|
+
environment: command.environment,
|
|
46925
|
+
idempotencyKey: command.idempotencyKey,
|
|
46926
|
+
watchId: command.watchId
|
|
46927
|
+
});
|
|
46928
|
+
return success("database watch delete", { status: "succeeded", deleted });
|
|
46929
|
+
}
|
|
46687
46930
|
/** The signing secret is returned by create only; every other answer carries no secret. */
|
|
46688
46931
|
async createDatabaseWebhook(command, signal) {
|
|
46689
46932
|
const request = await webhookCreateRequest(command);
|
|
@@ -47714,6 +47957,12 @@ var parsedCommandName = (command) => {
|
|
|
47714
47957
|
return "database access revoke";
|
|
47715
47958
|
if (command.kind === "database-psql")
|
|
47716
47959
|
return "database psql";
|
|
47960
|
+
if (command.kind === "database-watch-create")
|
|
47961
|
+
return "database watch create";
|
|
47962
|
+
if (command.kind === "database-watch-list")
|
|
47963
|
+
return "database watch list";
|
|
47964
|
+
if (command.kind === "database-watch-delete")
|
|
47965
|
+
return "database watch delete";
|
|
47717
47966
|
if (command.kind === "database-webhook-create")
|
|
47718
47967
|
return "database webhook create";
|
|
47719
47968
|
if (command.kind === "database-webhook-list")
|
|
@@ -50586,6 +50835,68 @@ var revokeProjectDatabaseAccess = (parameters, options) => {
|
|
|
50586
50835
|
...params
|
|
50587
50836
|
});
|
|
50588
50837
|
};
|
|
50838
|
+
var listProjectDatabaseWatches = (parameters, options) => {
|
|
50839
|
+
const params = buildClientParams([parameters], [
|
|
50840
|
+
{
|
|
50841
|
+
args: [
|
|
50842
|
+
{ in: "headers", key: "X-Request-Id" },
|
|
50843
|
+
{ in: "path", key: "project_id" },
|
|
50844
|
+
{ in: "query", key: "environment" }
|
|
50845
|
+
]
|
|
50846
|
+
}
|
|
50847
|
+
]);
|
|
50848
|
+
return (options?.client ?? client).get({
|
|
50849
|
+
responseStyle: "data",
|
|
50850
|
+
security: [{ scheme: "bearer", type: "http" }],
|
|
50851
|
+
url: "/v1/projects/{project_id}/database/watches",
|
|
50852
|
+
...options,
|
|
50853
|
+
...params
|
|
50854
|
+
});
|
|
50855
|
+
};
|
|
50856
|
+
var createProjectDatabaseWatch = (parameters, options) => {
|
|
50857
|
+
const params = buildClientParams([parameters], [
|
|
50858
|
+
{
|
|
50859
|
+
args: [
|
|
50860
|
+
{ in: "headers", key: "X-Request-Id" },
|
|
50861
|
+
{ in: "headers", key: "Idempotency-Key" },
|
|
50862
|
+
{ in: "path", key: "project_id" },
|
|
50863
|
+
{ key: "databaseWatchCreateRequest", map: "body" }
|
|
50864
|
+
]
|
|
50865
|
+
}
|
|
50866
|
+
]);
|
|
50867
|
+
return (options?.client ?? client).post({
|
|
50868
|
+
responseStyle: "data",
|
|
50869
|
+
security: [{ scheme: "bearer", type: "http" }],
|
|
50870
|
+
url: "/v1/projects/{project_id}/database/watches",
|
|
50871
|
+
...options,
|
|
50872
|
+
...params,
|
|
50873
|
+
headers: {
|
|
50874
|
+
"Content-Type": "application/json",
|
|
50875
|
+
...options?.headers,
|
|
50876
|
+
...params.headers
|
|
50877
|
+
}
|
|
50878
|
+
});
|
|
50879
|
+
};
|
|
50880
|
+
var deleteProjectDatabaseWatch = (parameters, options) => {
|
|
50881
|
+
const params = buildClientParams([parameters], [
|
|
50882
|
+
{
|
|
50883
|
+
args: [
|
|
50884
|
+
{ in: "headers", key: "X-Request-Id" },
|
|
50885
|
+
{ in: "headers", key: "Idempotency-Key" },
|
|
50886
|
+
{ in: "path", key: "project_id" },
|
|
50887
|
+
{ in: "path", key: "watch_id" },
|
|
50888
|
+
{ in: "query", key: "environment" }
|
|
50889
|
+
]
|
|
50890
|
+
}
|
|
50891
|
+
]);
|
|
50892
|
+
return (options?.client ?? client).delete({
|
|
50893
|
+
responseStyle: "data",
|
|
50894
|
+
security: [{ scheme: "bearer", type: "http" }],
|
|
50895
|
+
url: "/v1/projects/{project_id}/database/watches/{watch_id}",
|
|
50896
|
+
...options,
|
|
50897
|
+
...params
|
|
50898
|
+
});
|
|
50899
|
+
};
|
|
50589
50900
|
var listProjectDatabaseWebhooks = (parameters, options) => {
|
|
50590
50901
|
const params = buildClientParams([parameters], [
|
|
50591
50902
|
{
|
|
@@ -51959,6 +52270,7 @@ function checkedResponse(kind, value) {
|
|
|
51959
52270
|
|
|
51960
52271
|
// apps/product-cli/dist/product-api.js
|
|
51961
52272
|
var WEBHOOK_SCOPE_MISMATCH = "Webhook response scope mismatch";
|
|
52273
|
+
var WATCH_SCOPE_MISMATCH = "Watch response scope mismatch";
|
|
51962
52274
|
var SCHEDULE_SCOPE_MISMATCH = "Schedule response scope mismatch";
|
|
51963
52275
|
var GeneratedSdkProductApi = class {
|
|
51964
52276
|
#client;
|
|
@@ -52156,6 +52468,42 @@ var GeneratedSdkProductApi = class {
|
|
|
52156
52468
|
assertProjectDatabaseAccess(value);
|
|
52157
52469
|
return value;
|
|
52158
52470
|
}
|
|
52471
|
+
async createProjectDatabaseWatch(input) {
|
|
52472
|
+
const value = await createProjectDatabaseWatch({
|
|
52473
|
+
project_id: input.projectId,
|
|
52474
|
+
"Idempotency-Key": input.idempotencyKey,
|
|
52475
|
+
databaseWatchCreateRequest: {
|
|
52476
|
+
environment: input.environment,
|
|
52477
|
+
schema: input.request.schema,
|
|
52478
|
+
table: input.request.table,
|
|
52479
|
+
columns: [...input.request.columns],
|
|
52480
|
+
operations: [...input.request.operations]
|
|
52481
|
+
}
|
|
52482
|
+
}, { client: this.#client });
|
|
52483
|
+
assertDatabaseWatch(value);
|
|
52484
|
+
if (value.environment !== input.environment || value.schema !== input.request.schema || value.table !== input.request.table)
|
|
52485
|
+
throw new TypeError(WATCH_SCOPE_MISMATCH);
|
|
52486
|
+
return value;
|
|
52487
|
+
}
|
|
52488
|
+
async listProjectDatabaseWatches(input) {
|
|
52489
|
+
const value = await listProjectDatabaseWatches({ project_id: input.projectId, environment: input.environment }, { client: this.#client });
|
|
52490
|
+
assertDatabaseWatchPage(value);
|
|
52491
|
+
if (value.items.some((item) => item.environment !== input.environment))
|
|
52492
|
+
throw new TypeError(WATCH_SCOPE_MISMATCH);
|
|
52493
|
+
return value;
|
|
52494
|
+
}
|
|
52495
|
+
async deleteProjectDatabaseWatch(input) {
|
|
52496
|
+
const value = await deleteProjectDatabaseWatch({
|
|
52497
|
+
project_id: input.projectId,
|
|
52498
|
+
environment: input.environment,
|
|
52499
|
+
"Idempotency-Key": input.idempotencyKey,
|
|
52500
|
+
watch_id: input.watchId
|
|
52501
|
+
}, { client: this.#client });
|
|
52502
|
+
assertDatabaseWatchDeleted(value);
|
|
52503
|
+
if (value.id !== input.watchId)
|
|
52504
|
+
throw new TypeError(WATCH_SCOPE_MISMATCH);
|
|
52505
|
+
return value;
|
|
52506
|
+
}
|
|
52159
52507
|
/** The signing secret exists only in this answer; the CLI prints it once and stores nothing. */
|
|
52160
52508
|
async createProjectDatabaseWebhook(input) {
|
|
52161
52509
|
const value = await createProjectDatabaseWebhook({
|
|
@@ -54123,6 +54471,8 @@ function rejectMigrationSqlReferences(tokens, allowIdentityHelpers = false) {
|
|
|
54123
54471
|
if (token?.kind !== "word" && token?.kind !== "identifier")
|
|
54124
54472
|
continue;
|
|
54125
54473
|
const value = token.value.toLowerCase();
|
|
54474
|
+
if (value === "pgcf")
|
|
54475
|
+
throw new DatabaseMigrationAdmissionError("unsupported");
|
|
54126
54476
|
if (value === "ohmyhost") {
|
|
54127
54477
|
if (allowIdentityHelpers && token.value === "ohmyhost" && tokens[index + 1]?.kind === "symbol" && tokens[index + 1]?.value === "." && ["user_id", "claims"].includes(tokens[index + 2]?.value ?? "") && ["word", "identifier"].includes(tokens[index + 2]?.kind ?? "") && tokens[index + 3]?.kind === "symbol" && tokens[index + 3]?.value === "(" && tokens[index + 4]?.kind === "symbol" && tokens[index + 4]?.value === ")")
|
|
54128
54478
|
continue;
|
|
@@ -54134,6 +54484,139 @@ function rejectMigrationSqlReferences(tokens, allowIdentityHelpers = false) {
|
|
|
54134
54484
|
}
|
|
54135
54485
|
}
|
|
54136
54486
|
|
|
54487
|
+
// packages/contracts/dist/database-migration-capture.js
|
|
54488
|
+
var MAX_NAME_BYTES = 63;
|
|
54489
|
+
function readMigrationCaptureTrigger(tokens) {
|
|
54490
|
+
if (!isSqlKeyword(tokens[0], "create") || !isSqlKeyword(tokens[1], "trigger"))
|
|
54491
|
+
return void 0;
|
|
54492
|
+
if (!tokens.some((token) => isNamedPgcf(token, true)))
|
|
54493
|
+
return void 0;
|
|
54494
|
+
return new CaptureReader(tokens).read();
|
|
54495
|
+
}
|
|
54496
|
+
var CaptureReader = class {
|
|
54497
|
+
tokens;
|
|
54498
|
+
position = 2;
|
|
54499
|
+
constructor(tokens) {
|
|
54500
|
+
this.tokens = tokens;
|
|
54501
|
+
}
|
|
54502
|
+
read() {
|
|
54503
|
+
const trigger = this.triggerName();
|
|
54504
|
+
this.expectKeyword("after");
|
|
54505
|
+
const operations = this.operations();
|
|
54506
|
+
this.expectKeyword("on");
|
|
54507
|
+
const schema = this.name();
|
|
54508
|
+
this.expectSymbol(".");
|
|
54509
|
+
const table = this.name();
|
|
54510
|
+
if (!isDatabaseWatchSchema(schema))
|
|
54511
|
+
throw unsupported();
|
|
54512
|
+
for (const keyword of ["for", "each", "row", "execute", "function"]) {
|
|
54513
|
+
this.expectKeyword(keyword);
|
|
54514
|
+
}
|
|
54515
|
+
const header = this.tokens.slice(0, this.position);
|
|
54516
|
+
if (!isNamedPgcf(this.token(), false))
|
|
54517
|
+
throw unsupported();
|
|
54518
|
+
this.position += 1;
|
|
54519
|
+
this.expectSymbol(".");
|
|
54520
|
+
this.expectCapture();
|
|
54521
|
+
this.expectSymbol("(");
|
|
54522
|
+
const columns = this.columns();
|
|
54523
|
+
this.expectSymbol(")");
|
|
54524
|
+
if (this.position !== this.tokens.length)
|
|
54525
|
+
throw unsupported();
|
|
54526
|
+
return Object.freeze({
|
|
54527
|
+
target: Object.freeze({ trigger, schema, table, operations, columns }),
|
|
54528
|
+
header
|
|
54529
|
+
});
|
|
54530
|
+
}
|
|
54531
|
+
triggerName() {
|
|
54532
|
+
const token = this.token();
|
|
54533
|
+
if (token.kind !== "word" && token.kind !== "identifier" || !isDatabaseWatchIdentifier(token.value)) {
|
|
54534
|
+
throw unsupported();
|
|
54535
|
+
}
|
|
54536
|
+
this.position += 1;
|
|
54537
|
+
return token.value;
|
|
54538
|
+
}
|
|
54539
|
+
/** Table and schema names may be quoted identifiers; the executor checks the catalog for the exact name. */
|
|
54540
|
+
name() {
|
|
54541
|
+
const token = this.token();
|
|
54542
|
+
const valid = token.kind === "word" ? isDatabaseWatchIdentifier(token.value) : token.kind === "identifier" && isQuotedName(token.value);
|
|
54543
|
+
if (!valid)
|
|
54544
|
+
throw unsupported();
|
|
54545
|
+
this.position += 1;
|
|
54546
|
+
return token.value;
|
|
54547
|
+
}
|
|
54548
|
+
operations() {
|
|
54549
|
+
const events = [];
|
|
54550
|
+
do {
|
|
54551
|
+
const token = this.token();
|
|
54552
|
+
const operation = DATABASE_WATCH_OPERATIONS.find((name) => isSqlKeyword(token, name));
|
|
54553
|
+
if (operation === void 0 || events.includes(operation))
|
|
54554
|
+
throw unsupported();
|
|
54555
|
+
this.position += 1;
|
|
54556
|
+
events.push(operation);
|
|
54557
|
+
} while (this.takeKeyword("or"));
|
|
54558
|
+
return DATABASE_WATCH_OPERATIONS.filter((operation) => events.includes(operation));
|
|
54559
|
+
}
|
|
54560
|
+
expectCapture() {
|
|
54561
|
+
const token = this.token();
|
|
54562
|
+
if (token.kind !== "word" && token.kind !== "identifier" || token.value !== "capture") {
|
|
54563
|
+
throw unsupported();
|
|
54564
|
+
}
|
|
54565
|
+
this.position += 1;
|
|
54566
|
+
}
|
|
54567
|
+
columns() {
|
|
54568
|
+
const columns = [];
|
|
54569
|
+
do {
|
|
54570
|
+
const token = this.token();
|
|
54571
|
+
if (columns.length >= DATABASE_WATCH_MAX_COLUMNS || token.kind !== "string" || token.text !== `'${token.value}'` || !isDatabaseWatchIdentifier(token.value) || columns.includes(token.value)) {
|
|
54572
|
+
throw unsupported();
|
|
54573
|
+
}
|
|
54574
|
+
this.position += 1;
|
|
54575
|
+
columns.push(token.value);
|
|
54576
|
+
} while (this.takeSymbol(","));
|
|
54577
|
+
return columns;
|
|
54578
|
+
}
|
|
54579
|
+
token() {
|
|
54580
|
+
const token = this.tokens[this.position];
|
|
54581
|
+
if (token === void 0)
|
|
54582
|
+
throw unsupported();
|
|
54583
|
+
return token;
|
|
54584
|
+
}
|
|
54585
|
+
takeKeyword(keyword) {
|
|
54586
|
+
if (!isSqlKeyword(this.tokens[this.position], keyword))
|
|
54587
|
+
return false;
|
|
54588
|
+
this.position += 1;
|
|
54589
|
+
return true;
|
|
54590
|
+
}
|
|
54591
|
+
expectKeyword(keyword) {
|
|
54592
|
+
if (!this.takeKeyword(keyword))
|
|
54593
|
+
throw unsupported();
|
|
54594
|
+
}
|
|
54595
|
+
takeSymbol(symbol) {
|
|
54596
|
+
const token = this.tokens[this.position];
|
|
54597
|
+
if (token?.kind !== "symbol" || token.value !== symbol)
|
|
54598
|
+
return false;
|
|
54599
|
+
this.position += 1;
|
|
54600
|
+
return true;
|
|
54601
|
+
}
|
|
54602
|
+
expectSymbol(symbol) {
|
|
54603
|
+
if (!this.takeSymbol(symbol))
|
|
54604
|
+
throw unsupported();
|
|
54605
|
+
}
|
|
54606
|
+
};
|
|
54607
|
+
function isNamedPgcf(token, ignoreCase) {
|
|
54608
|
+
if (token.kind !== "word" && token.kind !== "identifier")
|
|
54609
|
+
return false;
|
|
54610
|
+
return ignoreCase ? token.value.toLowerCase() === "pgcf" : token.value === "pgcf";
|
|
54611
|
+
}
|
|
54612
|
+
function isQuotedName(value) {
|
|
54613
|
+
const bytes = new TextEncoder().encode(value).byteLength;
|
|
54614
|
+
return bytes >= 1 && bytes <= MAX_NAME_BYTES;
|
|
54615
|
+
}
|
|
54616
|
+
function unsupported() {
|
|
54617
|
+
return new DatabaseMigrationAdmissionError("unsupported");
|
|
54618
|
+
}
|
|
54619
|
+
|
|
54137
54620
|
// packages/contracts/dist/database-migration-policies.js
|
|
54138
54621
|
var PolicyReader = class {
|
|
54139
54622
|
tokens;
|
|
@@ -54287,6 +54770,9 @@ function admitExpandOnlyMigrations(migrations) {
|
|
|
54287
54770
|
throw new DatabaseMigrationAdmissionError("invalid");
|
|
54288
54771
|
}
|
|
54289
54772
|
const statements = parseDatabaseMigrationStatements(sql);
|
|
54773
|
+
if (statements.some((statement) => statement.captureTrigger !== void 0 && isDatabaseWatchTriggerName(statement.captureTrigger.trigger))) {
|
|
54774
|
+
throw new DatabaseMigrationAdmissionError("unsupported");
|
|
54775
|
+
}
|
|
54290
54776
|
statementCount += statements.length;
|
|
54291
54777
|
return Object.freeze({ path: migration.path, statementCount: statements.length });
|
|
54292
54778
|
});
|
|
@@ -54300,6 +54786,11 @@ function parseDatabaseMigrationStatements(sql) {
|
|
|
54300
54786
|
if (statements.length === 0)
|
|
54301
54787
|
throw new DatabaseMigrationAdmissionError("invalid");
|
|
54302
54788
|
return Object.freeze(statements.map((statement) => {
|
|
54789
|
+
const capture = readMigrationCaptureTrigger(statement.tokens);
|
|
54790
|
+
if (capture !== void 0) {
|
|
54791
|
+
rejectMigrationSqlReferences(capture.header);
|
|
54792
|
+
return Object.freeze({ sql: statement.sql, captureTrigger: capture.target });
|
|
54793
|
+
}
|
|
54303
54794
|
rejectMigrationSqlReferences(statement.tokens, true);
|
|
54304
54795
|
const rlsTarget = readMigrationRlsTarget(statement.tokens);
|
|
54305
54796
|
if (rlsTarget !== void 0)
|