@amerged/ohmyhost-cli 0.1.45 → 0.1.46
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-C6KEAOJP.js → chunk-A4ZYW4XW.js} +373 -56
- package/dist/index.js +3 -1
- package/package.json +1 -1
- package/src/apps/product-cli/package.json +1 -1
- package/src/apps/product-cli/src/cli.ts +76 -1
- package/src/apps/product-cli/src/command.ts +63 -0
- package/src/apps/product-cli/src/product-api.ts +116 -0
- package/src/packages/contracts/package.json +5 -0
- package/src/packages/contracts/src/database-tables.ts +317 -0
- package/src/packages/contracts/src/problem-policy.ts +14 -0
- package/src/packages/sdk-ts/package.json +1 -1
- package/src/packages/sdk-ts/src/generated/index.ts +12 -0
- package/src/packages/sdk-ts/src/generated/sdk.gen.ts +54 -0
- package/src/packages/sdk-ts/src/generated/types.gen.ts +141 -0
|
@@ -26645,7 +26645,7 @@ var require_discriminator = __commonJS({
|
|
|
26645
26645
|
error,
|
|
26646
26646
|
code(cxt) {
|
|
26647
26647
|
const { gen, data, schema, parentSchema, it } = cxt;
|
|
26648
|
-
const { oneOf:
|
|
26648
|
+
const { oneOf: oneOf3 } = parentSchema;
|
|
26649
26649
|
if (!it.opts.discriminator) {
|
|
26650
26650
|
throw new Error("discriminator: requires discriminator option");
|
|
26651
26651
|
}
|
|
@@ -26654,7 +26654,7 @@ var require_discriminator = __commonJS({
|
|
|
26654
26654
|
throw new Error("discriminator: requires propertyName");
|
|
26655
26655
|
if (schema.mapping)
|
|
26656
26656
|
throw new Error("discriminator: mapping is not supported");
|
|
26657
|
-
if (!
|
|
26657
|
+
if (!oneOf3)
|
|
26658
26658
|
throw new Error("discriminator: requires oneOf keyword");
|
|
26659
26659
|
const valid = gen.let("valid", false);
|
|
26660
26660
|
const tag = gen.const("tag", (0, codegen_1._)`${data}${(0, codegen_1.getProperty)(tagName)}`);
|
|
@@ -26682,8 +26682,8 @@ var require_discriminator = __commonJS({
|
|
|
26682
26682
|
const oneOfMapping = {};
|
|
26683
26683
|
const topRequired = hasRequired(parentSchema);
|
|
26684
26684
|
let tagRequired = true;
|
|
26685
|
-
for (let i = 0; i <
|
|
26686
|
-
let sch =
|
|
26685
|
+
for (let i = 0; i < oneOf3.length; i++) {
|
|
26686
|
+
let sch = oneOf3[i];
|
|
26687
26687
|
if ((sch === null || sch === void 0 ? void 0 : sch.$ref) && !(0, util_1.schemaHasRulesButRef)(sch, it.self.RULES)) {
|
|
26688
26688
|
const ref = sch.$ref;
|
|
26689
26689
|
sch = compile_1.resolveRef.call(it.self, it.schemaEnv.root, it.baseId, ref);
|
|
@@ -38776,14 +38776,14 @@ function isFrameworkConversionDiagnosticCode(value) {
|
|
|
38776
38776
|
function parseFrameworkConversionDiagnostic(value) {
|
|
38777
38777
|
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
38778
38778
|
return null;
|
|
38779
|
-
const
|
|
38780
|
-
const code = Object.hasOwn(
|
|
38781
|
-
const path2 = Object.hasOwn(
|
|
38779
|
+
const record8 = value;
|
|
38780
|
+
const code = Object.hasOwn(record8, "code") ? record8["code"] : void 0;
|
|
38781
|
+
const path2 = Object.hasOwn(record8, "path") ? record8["path"] : void 0;
|
|
38782
38782
|
if (!isFrameworkConversionDiagnosticCode(code) || typeof path2 !== "string")
|
|
38783
38783
|
return null;
|
|
38784
38784
|
const definition = DETAIL_DEFINITIONS[code];
|
|
38785
|
-
const fields = Object.entries(definition.fields ?? {}).map(([name, grammar]) => [name, grammar, Object.hasOwn(
|
|
38786
|
-
if (Object.keys(
|
|
38785
|
+
const fields = Object.entries(definition.fields ?? {}).map(([name, grammar]) => [name, grammar, Object.hasOwn(record8, name) ? record8[name] : void 0]);
|
|
38786
|
+
if (Object.keys(record8).length !== fields.length + 2 || pathClassOf(definition, path2) === null || fields.some(([, grammar, field]) => !fieldMatches(grammar, field)))
|
|
38787
38787
|
return null;
|
|
38788
38788
|
return Object.freeze(Object.fromEntries([
|
|
38789
38789
|
["code", code],
|
|
@@ -40249,6 +40249,18 @@ var PROBLEM_POLICY = {
|
|
|
40249
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
40250
|
title: "Table already has a capture trigger"
|
|
40251
40251
|
},
|
|
40252
|
+
database_table_conflict: {
|
|
40253
|
+
status: 409,
|
|
40254
|
+
retryable: false,
|
|
40255
|
+
action: "A table with this name already exists with another definition. Choose another table name, or create the table again with the same columns, types, nullability, identity, defaults and primary key it has.",
|
|
40256
|
+
title: "Table already exists with another definition"
|
|
40257
|
+
},
|
|
40258
|
+
database_table_limit: {
|
|
40259
|
+
status: 409,
|
|
40260
|
+
retryable: false,
|
|
40261
|
+
action: "This database already holds the maximum number of tables in its public schema, so no table can be added. Use an existing table, or remove a table you no longer need through a deployed migration, then create the table again.",
|
|
40262
|
+
title: "Database table limit reached"
|
|
40263
|
+
},
|
|
40252
40264
|
project_notes_conflict: {
|
|
40253
40265
|
status: 409,
|
|
40254
40266
|
retryable: false,
|
|
@@ -41384,8 +41396,8 @@ var isPaidValidationRecord = (value) => {
|
|
|
41384
41396
|
if (typeof value !== "object" || value === null || Array.isArray(value) || Object.keys(value).sort().join(",") !== "content,name,purpose,type") {
|
|
41385
41397
|
return false;
|
|
41386
41398
|
}
|
|
41387
|
-
const
|
|
41388
|
-
return (
|
|
41399
|
+
const record8 = value;
|
|
41400
|
+
return (record8["type"] === "CNAME" || record8["type"] === "TXT") && boundedString(record8["name"], 1, 253) && boundedString(record8["content"], 1, 2048) && ["traffic", "ownership", "ssl", "dcv_delegation"].includes(String(record8["purpose"]));
|
|
41389
41401
|
};
|
|
41390
41402
|
var isHttpsUrlValue = (value) => typeof value === "string" && isHttpsUrl(value);
|
|
41391
41403
|
|
|
@@ -41530,7 +41542,7 @@ async function prepareLocalSourcePublication(input) {
|
|
|
41530
41542
|
request = { ...request, expected_commit_sha: link2.source.last_confirmed_commit_sha };
|
|
41531
41543
|
}
|
|
41532
41544
|
parseManagedSourceRequest("upload", request);
|
|
41533
|
-
const
|
|
41545
|
+
const record8 = {
|
|
41534
41546
|
version: 1,
|
|
41535
41547
|
...scope,
|
|
41536
41548
|
operation_id: null,
|
|
@@ -41539,16 +41551,16 @@ async function prepareLocalSourcePublication(input) {
|
|
|
41539
41551
|
request
|
|
41540
41552
|
};
|
|
41541
41553
|
if (original !== null) {
|
|
41542
|
-
assertSameAttempt(original,
|
|
41554
|
+
assertSameAttempt(original, record8);
|
|
41543
41555
|
} else
|
|
41544
|
-
await writePending(
|
|
41556
|
+
await writePending(record8, true);
|
|
41545
41557
|
return {
|
|
41546
41558
|
request,
|
|
41547
41559
|
accepted: async (operation) => {
|
|
41548
41560
|
const current = await readPending(scope, replay);
|
|
41549
41561
|
if (current === null)
|
|
41550
41562
|
throw new LocalSourcePublicationError("source_publication_missing");
|
|
41551
|
-
assertSameAttempt(current,
|
|
41563
|
+
assertSameAttempt(current, record8);
|
|
41552
41564
|
if (current.operation_id !== null && current.operation_id !== operation.id)
|
|
41553
41565
|
throw new ResponseContractError();
|
|
41554
41566
|
if (!replay)
|
|
@@ -41567,7 +41579,7 @@ async function prepareLocalSourcePublication(input) {
|
|
|
41567
41579
|
const current = await readPending(scope);
|
|
41568
41580
|
if (current === null || current.operation_id !== null)
|
|
41569
41581
|
return;
|
|
41570
|
-
assertSameAttempt(current,
|
|
41582
|
+
assertSameAttempt(current, record8);
|
|
41571
41583
|
} catch (error2) {
|
|
41572
41584
|
if (error2 instanceof LocalSourcePublicationError && (error2.code === "source_publication_scope_mismatch" || error2.code === "source_publication_pending"))
|
|
41573
41585
|
return;
|
|
@@ -41770,12 +41782,12 @@ async function readRecord(path2) {
|
|
|
41770
41782
|
await handle?.close();
|
|
41771
41783
|
}
|
|
41772
41784
|
}
|
|
41773
|
-
async function writePending(
|
|
41774
|
-
const parent = join3(
|
|
41785
|
+
async function writePending(record8, create, completed = false) {
|
|
41786
|
+
const parent = join3(record8.directory, ".ohmyhost");
|
|
41775
41787
|
for (const directory of [
|
|
41776
41788
|
parent,
|
|
41777
|
-
|
|
41778
|
-
join3(
|
|
41789
|
+
record8.metadata_directory,
|
|
41790
|
+
join3(record8.metadata_directory, "publications")
|
|
41779
41791
|
]) {
|
|
41780
41792
|
try {
|
|
41781
41793
|
await fs2.mkdir(directory, { mode: 448 });
|
|
@@ -41786,10 +41798,10 @@ async function writePending(record7, create, completed = false) {
|
|
|
41786
41798
|
await checkedDirectory(directory);
|
|
41787
41799
|
await fs2.chmod(directory, 448);
|
|
41788
41800
|
}
|
|
41789
|
-
const target = completed ? completedPath(
|
|
41801
|
+
const target = completed ? completedPath(record8) : pendingPath(record8);
|
|
41790
41802
|
const temporary = create ? target : `${target}.${randomUUID()}.tmp`;
|
|
41791
41803
|
try {
|
|
41792
|
-
await fs2.writeFile(temporary, `${JSON.stringify(
|
|
41804
|
+
await fs2.writeFile(temporary, `${JSON.stringify(record8)}
|
|
41793
41805
|
`, { mode: 384, flag: "wx" });
|
|
41794
41806
|
if (!create)
|
|
41795
41807
|
await fs2.rename(temporary, target);
|
|
@@ -42849,6 +42861,170 @@ function exact2(value, keys) {
|
|
|
42849
42861
|
return Object.keys(value).sort().join(",") === [...keys].sort().join(",");
|
|
42850
42862
|
}
|
|
42851
42863
|
|
|
42864
|
+
// packages/contracts/dist/database-tables.js
|
|
42865
|
+
var DATABASE_TABLE_COLUMN_TYPES = [
|
|
42866
|
+
"text",
|
|
42867
|
+
"integer",
|
|
42868
|
+
"bigint",
|
|
42869
|
+
"boolean",
|
|
42870
|
+
"numeric",
|
|
42871
|
+
"double precision",
|
|
42872
|
+
"timestamptz",
|
|
42873
|
+
"date",
|
|
42874
|
+
"uuid",
|
|
42875
|
+
"jsonb"
|
|
42876
|
+
];
|
|
42877
|
+
var DATABASE_TABLE_DEFAULTS = ["now", "uuid"];
|
|
42878
|
+
var DATABASE_TABLE_MAX_COLUMNS = 64;
|
|
42879
|
+
var DATABASE_TABLE_MAX_PRIMARY_KEY_COLUMNS = 8;
|
|
42880
|
+
var DATABASE_TABLE_IDENTIFIER_PATTERN = /^[a-z_][a-z0-9_]{0,62}$/u;
|
|
42881
|
+
var RESERVED_WORDS = /* @__PURE__ */ new Set([
|
|
42882
|
+
"all",
|
|
42883
|
+
"analyse",
|
|
42884
|
+
"analyze",
|
|
42885
|
+
"and",
|
|
42886
|
+
"any",
|
|
42887
|
+
"array",
|
|
42888
|
+
"as",
|
|
42889
|
+
"asc",
|
|
42890
|
+
"asymmetric",
|
|
42891
|
+
"both",
|
|
42892
|
+
"case",
|
|
42893
|
+
"cast",
|
|
42894
|
+
"check",
|
|
42895
|
+
"collate",
|
|
42896
|
+
"column",
|
|
42897
|
+
"constraint",
|
|
42898
|
+
"create",
|
|
42899
|
+
"current_catalog",
|
|
42900
|
+
"current_date",
|
|
42901
|
+
"current_role",
|
|
42902
|
+
"current_time",
|
|
42903
|
+
"current_timestamp",
|
|
42904
|
+
"current_user",
|
|
42905
|
+
"default",
|
|
42906
|
+
"deferrable",
|
|
42907
|
+
"desc",
|
|
42908
|
+
"distinct",
|
|
42909
|
+
"do",
|
|
42910
|
+
"else",
|
|
42911
|
+
"end",
|
|
42912
|
+
"except",
|
|
42913
|
+
"false",
|
|
42914
|
+
"fetch",
|
|
42915
|
+
"for",
|
|
42916
|
+
"foreign",
|
|
42917
|
+
"from",
|
|
42918
|
+
"grant",
|
|
42919
|
+
"group",
|
|
42920
|
+
"having",
|
|
42921
|
+
"in",
|
|
42922
|
+
"initially",
|
|
42923
|
+
"intersect",
|
|
42924
|
+
"into",
|
|
42925
|
+
"lateral",
|
|
42926
|
+
"leading",
|
|
42927
|
+
"limit",
|
|
42928
|
+
"localtime",
|
|
42929
|
+
"localtimestamp",
|
|
42930
|
+
"not",
|
|
42931
|
+
"null",
|
|
42932
|
+
"offset",
|
|
42933
|
+
"on",
|
|
42934
|
+
"only",
|
|
42935
|
+
"or",
|
|
42936
|
+
"order",
|
|
42937
|
+
"placing",
|
|
42938
|
+
"primary",
|
|
42939
|
+
"references",
|
|
42940
|
+
"returning",
|
|
42941
|
+
"select",
|
|
42942
|
+
"session_user",
|
|
42943
|
+
"some",
|
|
42944
|
+
"symmetric",
|
|
42945
|
+
"table",
|
|
42946
|
+
"then",
|
|
42947
|
+
"to",
|
|
42948
|
+
"trailing",
|
|
42949
|
+
"true",
|
|
42950
|
+
"union",
|
|
42951
|
+
"unique",
|
|
42952
|
+
"user",
|
|
42953
|
+
"using",
|
|
42954
|
+
"variadic",
|
|
42955
|
+
"when",
|
|
42956
|
+
"where",
|
|
42957
|
+
"window",
|
|
42958
|
+
"with"
|
|
42959
|
+
]);
|
|
42960
|
+
function isDatabaseTableIdentifier(value) {
|
|
42961
|
+
return typeof value === "string" && DATABASE_TABLE_IDENTIFIER_PATTERN.test(value) && !value.startsWith("pg_") && !RESERVED_WORDS.has(value);
|
|
42962
|
+
}
|
|
42963
|
+
function parseDatabaseTableCreateRequest(value) {
|
|
42964
|
+
if (!record3(value) || !onlyKeys2(value, ["table", "columns", "primaryKey"]) || !isDatabaseTableIdentifier(value["table"]) || !Array.isArray(value["columns"]) || value["columns"].length < 1 || value["columns"].length > DATABASE_TABLE_MAX_COLUMNS)
|
|
42965
|
+
throw new TypeError("Invalid database table request");
|
|
42966
|
+
const inputs = value["columns"].map(parseColumn);
|
|
42967
|
+
const names = inputs.map((column) => column.name);
|
|
42968
|
+
if (new Set(names).size !== names.length || inputs.filter((column) => column.identity).length > 1)
|
|
42969
|
+
throw new TypeError("Invalid database table request");
|
|
42970
|
+
const primaryKey = parsePrimaryKey(value["primaryKey"], names);
|
|
42971
|
+
return {
|
|
42972
|
+
table: value["table"],
|
|
42973
|
+
columns: inputs.map((column) => completeColumn(column, primaryKey.includes(column.name))),
|
|
42974
|
+
primaryKey
|
|
42975
|
+
};
|
|
42976
|
+
}
|
|
42977
|
+
function parseColumn(value) {
|
|
42978
|
+
if (!record3(value) || !onlyKeys2(value, ["name", "type", "nullable", "identity", "default"]) || !isDatabaseTableIdentifier(value["name"]) || !oneOf2(DATABASE_TABLE_COLUMN_TYPES, value["type"]) || value["nullable"] !== void 0 && typeof value["nullable"] !== "boolean" || value["identity"] !== void 0 && typeof value["identity"] !== "boolean" || value["default"] !== void 0 && !oneOf2(DATABASE_TABLE_DEFAULTS, value["default"]))
|
|
42979
|
+
throw new TypeError("Invalid database table request");
|
|
42980
|
+
const type = value["type"];
|
|
42981
|
+
const identity = value["identity"] === true;
|
|
42982
|
+
const defaultValue = value["default"] ?? null;
|
|
42983
|
+
if (identity && type !== "integer" && type !== "bigint")
|
|
42984
|
+
throw new TypeError("Invalid database table request");
|
|
42985
|
+
if (identity && defaultValue !== null)
|
|
42986
|
+
throw new TypeError("Invalid database table request");
|
|
42987
|
+
if (defaultValue === "now" && type !== "timestamptz")
|
|
42988
|
+
throw new TypeError("Invalid database table request");
|
|
42989
|
+
if (defaultValue === "uuid" && type !== "uuid")
|
|
42990
|
+
throw new TypeError("Invalid database table request");
|
|
42991
|
+
return {
|
|
42992
|
+
name: value["name"],
|
|
42993
|
+
type,
|
|
42994
|
+
nullable: value["nullable"],
|
|
42995
|
+
identity,
|
|
42996
|
+
default: defaultValue
|
|
42997
|
+
};
|
|
42998
|
+
}
|
|
42999
|
+
function parsePrimaryKey(value, names) {
|
|
43000
|
+
if (value === void 0)
|
|
43001
|
+
return [];
|
|
43002
|
+
if (!Array.isArray(value) || value.length < 1 || value.length > DATABASE_TABLE_MAX_PRIMARY_KEY_COLUMNS || new Set(value).size !== value.length || !value.every((name) => typeof name === "string" && names.includes(name)))
|
|
43003
|
+
throw new TypeError("Invalid database table request");
|
|
43004
|
+
return value;
|
|
43005
|
+
}
|
|
43006
|
+
function completeColumn(column, keyed) {
|
|
43007
|
+
const required = column.identity || keyed;
|
|
43008
|
+
if (required && column.nullable === true)
|
|
43009
|
+
throw new TypeError("Invalid database table request");
|
|
43010
|
+
return {
|
|
43011
|
+
name: column.name,
|
|
43012
|
+
type: column.type,
|
|
43013
|
+
nullable: required ? false : column.nullable ?? true,
|
|
43014
|
+
identity: column.identity,
|
|
43015
|
+
default: column.default
|
|
43016
|
+
};
|
|
43017
|
+
}
|
|
43018
|
+
function oneOf2(allowed, value) {
|
|
43019
|
+
return typeof value === "string" && allowed.includes(value);
|
|
43020
|
+
}
|
|
43021
|
+
function record3(value) {
|
|
43022
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
43023
|
+
}
|
|
43024
|
+
function onlyKeys2(value, allowed) {
|
|
43025
|
+
return Object.keys(value).every((key) => allowed.includes(key));
|
|
43026
|
+
}
|
|
43027
|
+
|
|
42852
43028
|
// packages/contracts/dist/database-sizes.js
|
|
42853
43029
|
var DATABASE_SIZES = Object.freeze([
|
|
42854
43030
|
Object.freeze({
|
|
@@ -43217,6 +43393,8 @@ var recognizedCommandLabel = (argv) => {
|
|
|
43217
43393
|
if (values[1] === "delete")
|
|
43218
43394
|
return "database watch delete";
|
|
43219
43395
|
}
|
|
43396
|
+
if (value === "database" && values[0] === "table" && values[1] === "create")
|
|
43397
|
+
return "database table create";
|
|
43220
43398
|
if (value === "database" && values[0] === "webhook") {
|
|
43221
43399
|
if (values[1] === "create")
|
|
43222
43400
|
return "database webhook create";
|
|
@@ -44133,6 +44311,38 @@ var parseProductCliCommand = (argv) => {
|
|
|
44133
44311
|
}
|
|
44134
44312
|
throw new InvalidCommandError();
|
|
44135
44313
|
}
|
|
44314
|
+
if (first === "database" && values[0] === "table") {
|
|
44315
|
+
values.shift();
|
|
44316
|
+
const subcommand = values.shift();
|
|
44317
|
+
if (subcommand === "create") {
|
|
44318
|
+
if (!yes || wait || follow || revoke || stdin)
|
|
44319
|
+
throw new InvalidCommandError();
|
|
44320
|
+
const options = parseOptionalOptions(values, [
|
|
44321
|
+
"--project",
|
|
44322
|
+
"--environment",
|
|
44323
|
+
"--table",
|
|
44324
|
+
"--columns-file",
|
|
44325
|
+
"--primary-key",
|
|
44326
|
+
"--idempotency-key"
|
|
44327
|
+
]);
|
|
44328
|
+
const projectId = options["--project"], environment = options["--environment"], table = options["--table"], columnsFile = options["--columns-file"], primaryKey = options["--primary-key"], idempotencyKey = options["--idempotency-key"];
|
|
44329
|
+
const keyNames = primaryKey === void 0 ? [] : primaryKey.split(",");
|
|
44330
|
+
if (!isValue(projectId) || !isValue(idempotencyKey) || !isValue(table) || !isValue(columnsFile) || primaryKey !== void 0 && !keyNames.every(isDatabaseTableIdentifier) || keyNames.length > DATABASE_TABLE_MAX_PRIMARY_KEY_COLUMNS || !isDatabaseTableIdentifier(table) || environment !== "dev" && environment !== "prod")
|
|
44331
|
+
throw new InvalidCommandError();
|
|
44332
|
+
return {
|
|
44333
|
+
kind: "database-table-create",
|
|
44334
|
+
projectId,
|
|
44335
|
+
environment,
|
|
44336
|
+
table,
|
|
44337
|
+
columnsFile,
|
|
44338
|
+
primaryKey: keyNames,
|
|
44339
|
+
idempotencyKey,
|
|
44340
|
+
yes: true,
|
|
44341
|
+
credentialStore
|
|
44342
|
+
};
|
|
44343
|
+
}
|
|
44344
|
+
throw new InvalidCommandError();
|
|
44345
|
+
}
|
|
44136
44346
|
if (first === "database" && values[0] === "webhook") {
|
|
44137
44347
|
values.shift();
|
|
44138
44348
|
const subcommand = values.shift();
|
|
@@ -45279,7 +45489,7 @@ import { join as join5, resolve as resolve4 } from "node:path";
|
|
|
45279
45489
|
|
|
45280
45490
|
// packages/contracts/dist/database-access.js
|
|
45281
45491
|
function parseProjectDatabaseWrite(value) {
|
|
45282
|
-
if (!
|
|
45492
|
+
if (!record4(value) || !exact3(value, ["environment", "statement", "parameters"]) || !["dev", "prod"].includes(String(value["environment"])) || typeof value["statement"] !== "string" || !/^\s*(?:insert|update|delete)\b/iu.test(value["statement"]) || new TextEncoder().encode(value["statement"]).byteLength > 65536 || value["statement"].includes("\0") || !Array.isArray(value["parameters"]) || value["parameters"].length > 100)
|
|
45283
45493
|
throw new TypeError("Invalid database write");
|
|
45284
45494
|
const budget = { nodes: 0 };
|
|
45285
45495
|
for (const parameter of value["parameters"])
|
|
@@ -45293,7 +45503,7 @@ function parseProjectDatabaseWrite(value) {
|
|
|
45293
45503
|
};
|
|
45294
45504
|
}
|
|
45295
45505
|
function assertProjectDatabaseWriteReceipt(value) {
|
|
45296
|
-
if (!
|
|
45506
|
+
if (!record4(value) || !exact3(value, ["operation_id", "environment", "state", "command", "affected_rows", "error"]) || typeof value["operation_id"] !== "string" || !/^[0-7][0-9A-HJKMNP-TV-Z]{25}$/u.test(value["operation_id"]) || !["dev", "prod"].includes(String(value["environment"])) || !["running", "succeeded", "failed"].includes(String(value["state"])))
|
|
45297
45507
|
throw new TypeError("Invalid database write receipt");
|
|
45298
45508
|
if (value["state"] === "succeeded") {
|
|
45299
45509
|
if (!["INSERT", "UPDATE", "DELETE"].includes(String(value["command"])) || !Number.isSafeInteger(value["affected_rows"]) || Number(value["affected_rows"]) < 0 || Number(value["affected_rows"]) > 1e3 || value["error"] !== null)
|
|
@@ -45306,7 +45516,7 @@ function assertProjectDatabaseWriteReceipt(value) {
|
|
|
45306
45516
|
throw new TypeError("Invalid database write result");
|
|
45307
45517
|
} else {
|
|
45308
45518
|
const error = value["error"];
|
|
45309
|
-
if (!
|
|
45519
|
+
if (!record4(error) || typeof error["code"] !== "string" || !error["code"].startsWith("database_write_") || JSON.stringify(error) !== JSON.stringify(publicOperationFailure(error["code"])))
|
|
45310
45520
|
throw new TypeError("Invalid database write error");
|
|
45311
45521
|
}
|
|
45312
45522
|
}
|
|
@@ -45330,12 +45540,12 @@ var ACCESS_KEYS = [
|
|
|
45330
45540
|
];
|
|
45331
45541
|
var ACCESS_ROLE_PATTERN = /^ohmyho_da_[0-7][0-9a-hjkmnp-tv-z]{25}_[0-9a-z]{8}$/u;
|
|
45332
45542
|
function assertProjectDatabaseAccess(value) {
|
|
45333
|
-
if (!
|
|
45543
|
+
if (!record4(value) || !exact3(value, ACCESS_KEYS))
|
|
45334
45544
|
throw new TypeError("Invalid database access");
|
|
45335
45545
|
assertAccessFields(value);
|
|
45336
45546
|
}
|
|
45337
45547
|
function assertProjectDatabaseAccessCredential(value) {
|
|
45338
|
-
if (!
|
|
45548
|
+
if (!record4(value) || !exact3(value, [...ACCESS_KEYS, "connection_uri", "psql_command"]))
|
|
45339
45549
|
throw new TypeError("Invalid database access credential");
|
|
45340
45550
|
assertAccessFields(value);
|
|
45341
45551
|
const uri = value["connection_uri"];
|
|
@@ -45351,7 +45561,7 @@ function assertProjectDatabaseAccessCredential(value) {
|
|
|
45351
45561
|
throw new TypeError("Invalid database access credential");
|
|
45352
45562
|
}
|
|
45353
45563
|
function assertProjectDatabaseAccessPage(value) {
|
|
45354
|
-
if (!
|
|
45564
|
+
if (!record4(value) || !exact3(value, ["items"]) || !Array.isArray(value["items"]) || value["items"].length > 50)
|
|
45355
45565
|
throw new TypeError("Invalid database access page");
|
|
45356
45566
|
for (const item of value["items"])
|
|
45357
45567
|
assertProjectDatabaseAccess(item);
|
|
@@ -45386,14 +45596,14 @@ function json(value, depth, budget) {
|
|
|
45386
45596
|
json(entry, depth + 1, budget);
|
|
45387
45597
|
return;
|
|
45388
45598
|
}
|
|
45389
|
-
if (
|
|
45599
|
+
if (record4(value)) {
|
|
45390
45600
|
for (const entry of Object.values(value))
|
|
45391
45601
|
json(entry, depth + 1, budget);
|
|
45392
45602
|
return;
|
|
45393
45603
|
}
|
|
45394
45604
|
throw new TypeError("Invalid database parameter");
|
|
45395
45605
|
}
|
|
45396
|
-
function
|
|
45606
|
+
function record4(value) {
|
|
45397
45607
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
45398
45608
|
}
|
|
45399
45609
|
function exact3(value, keys) {
|
|
@@ -45402,7 +45612,7 @@ function exact3(value, keys) {
|
|
|
45402
45612
|
|
|
45403
45613
|
// packages/contracts/dist/credit-pricing.js
|
|
45404
45614
|
function assertOrganizationCreditUsage(value) {
|
|
45405
|
-
const
|
|
45615
|
+
const record8 = (input, keys) => {
|
|
45406
45616
|
if (!input || typeof input !== "object" || Array.isArray(input) || Object.keys(input).sort().join() !== keys.split(",").sort().join())
|
|
45407
45617
|
throw new TypeError("Invalid usage fields");
|
|
45408
45618
|
return input;
|
|
@@ -45410,30 +45620,30 @@ function assertOrganizationCreditUsage(value) {
|
|
|
45410
45620
|
const identifier2 = (input) => typeof input === "string" && /^[0-7][0-9A-HJKMNP-TV-Z]{25}$/u.test(input);
|
|
45411
45621
|
const amount = (input) => typeof input === "string" && /^(0|[1-9][0-9]{0,37})$/u.test(input);
|
|
45412
45622
|
const instant2 = (input) => typeof input === "string" && Number.isFinite(Date.parse(input)) && new Date(input).toISOString() === input;
|
|
45413
|
-
const report =
|
|
45623
|
+
const report = record8(value, "organization_id,as_of,unit,period,from,projects,days");
|
|
45414
45624
|
if (!identifier2(report["organization_id"]) || !instant2(report["as_of"]) || !instant2(report["from"]) || report["unit"] !== "microcredits" || typeof report["period"] !== "string" || !/^20[0-9]{2}-(0[1-9]|1[0-2])$/u.test(report["period"]) || !Array.isArray(report["projects"]) || report["projects"].length > 1e3 || !Array.isArray(report["days"]) || report["days"].length > 15)
|
|
45415
45625
|
throw new TypeError("Invalid usage report");
|
|
45416
45626
|
let previous = "";
|
|
45417
45627
|
for (const input of report["projects"]) {
|
|
45418
|
-
const project =
|
|
45628
|
+
const project = record8(input, "project_id,used_micros");
|
|
45419
45629
|
if (!identifier2(project["project_id"]) || String(project["project_id"]) <= previous || !amount(project["used_micros"]))
|
|
45420
45630
|
throw new TypeError("Invalid usage project");
|
|
45421
45631
|
previous = String(project["project_id"]);
|
|
45422
45632
|
}
|
|
45423
45633
|
let previousDay = "";
|
|
45424
45634
|
for (const input of report["days"]) {
|
|
45425
|
-
const day =
|
|
45635
|
+
const day = record8(input, "day,projects");
|
|
45426
45636
|
if (typeof day["day"] !== "string" || !/^20[0-9]{2}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$/u.test(day["day"]) || day["day"] <= previousDay || !Array.isArray(day["projects"]) || day["projects"].length > 1e3)
|
|
45427
45637
|
throw new TypeError("Invalid usage day");
|
|
45428
45638
|
previousDay = day["day"];
|
|
45429
45639
|
previous = "";
|
|
45430
45640
|
for (const projectInput of day["projects"]) {
|
|
45431
|
-
const project =
|
|
45641
|
+
const project = record8(projectInput, "project_id,meters");
|
|
45432
45642
|
if (!identifier2(project["project_id"]) || String(project["project_id"]) <= previous || !Array.isArray(project["meters"]) || project["meters"].length > 1e3)
|
|
45433
45643
|
throw new TypeError("Invalid usage project");
|
|
45434
45644
|
previous = String(project["project_id"]);
|
|
45435
45645
|
for (const meterInput of project["meters"]) {
|
|
45436
|
-
const meter =
|
|
45646
|
+
const meter = record8(meterInput, "environment_id,meter,unit,rate_card_id,quantity,charged_micros");
|
|
45437
45647
|
if (meter["environment_id"] !== null && !identifier2(meter["environment_id"]))
|
|
45438
45648
|
throw new TypeError("Invalid usage environment");
|
|
45439
45649
|
for (const key of ["meter", "unit", "rate_card_id"])
|
|
@@ -45468,16 +45678,16 @@ function assertOrganizationAccount(value) {
|
|
|
45468
45678
|
|
|
45469
45679
|
// packages/contracts/dist/database-compute.js
|
|
45470
45680
|
function assertDatabaseCompute(value) {
|
|
45471
|
-
if (!
|
|
45681
|
+
if (!record5(value) || !exact4(value, ["data_mode", "database", "environment", "observed_at", "project_id"]) || typeof value["project_id"] !== "string" || !/^[0-7][0-9A-HJKMNP-TV-Z]{25}$/u.test(value["project_id"]) || !["dev", "prod"].includes(String(value["environment"])) || !["shared", "isolated"].includes(String(value["data_mode"])) || typeof value["observed_at"] !== "string" || !Number.isFinite(Date.parse(value["observed_at"])) || new Date(value["observed_at"]).toISOString() !== value["observed_at"])
|
|
45472
45682
|
throw new TypeError("Invalid database compute report");
|
|
45473
45683
|
const db = value["database"];
|
|
45474
45684
|
if (db === null)
|
|
45475
45685
|
return;
|
|
45476
|
-
if (
|
|
45686
|
+
if (record5(db) && db["provider"] === "pgcf") {
|
|
45477
45687
|
assertPgcfCompute(db);
|
|
45478
45688
|
return;
|
|
45479
45689
|
}
|
|
45480
|
-
if (!
|
|
45690
|
+
if (!record5(db) || !exact4(db, [
|
|
45481
45691
|
"disabled",
|
|
45482
45692
|
"max_cu",
|
|
45483
45693
|
"max_memory_gb",
|
|
@@ -45508,7 +45718,7 @@ function assertPgcfCompute(db) {
|
|
|
45508
45718
|
]) || db["memory_mib"] !== size.memoryMiB || db["cpu_millicores"] !== size.cpuMillicores || db["storage_mib"] !== size.storageMiB || db["max_connections"] !== size.maxConnections || !Number.isSafeInteger(db["suspend_timeout_seconds"]) || Number(db["suspend_timeout_seconds"]) < 60 || Number(db["suspend_timeout_seconds"]) > 900 || !states.includes(String(db["state"])) || db["pending_state"] !== null && !states.includes(String(db["pending_state"])) || typeof db["disabled"] !== "boolean" || !["us", "eu"].includes(String(db["region"])))
|
|
45509
45719
|
throw new TypeError("Invalid fixed database compute configuration");
|
|
45510
45720
|
}
|
|
45511
|
-
function
|
|
45721
|
+
function record5(v) {
|
|
45512
45722
|
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
45513
45723
|
}
|
|
45514
45724
|
function exact4(v, keys) {
|
|
@@ -45518,7 +45728,7 @@ function exact4(v, keys) {
|
|
|
45518
45728
|
// apps/product-cli/package.json
|
|
45519
45729
|
var package_default = {
|
|
45520
45730
|
name: "@ohmyhost/product-cli",
|
|
45521
|
-
version: "0.1.
|
|
45731
|
+
version: "0.1.46",
|
|
45522
45732
|
private: true,
|
|
45523
45733
|
ohmyhost: {
|
|
45524
45734
|
deployment: "production",
|
|
@@ -45565,32 +45775,32 @@ var package_default = {
|
|
|
45565
45775
|
};
|
|
45566
45776
|
|
|
45567
45777
|
// packages/contracts/dist/project-context.js
|
|
45568
|
-
var
|
|
45778
|
+
var record6 = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
45569
45779
|
var timestamp4 = (v) => typeof v === "string" && Number.isFinite(Date.parse(v)) && new Date(v).toISOString() === v;
|
|
45570
45780
|
var version = (v) => Number.isInteger(v) && Number(v) >= 0 && Number(v) <= 2147483647;
|
|
45571
45781
|
var bounded = (v, lines, bytes) => typeof v === "string" && !/[\r\u2028\u2029]/u.test(v) && !new RegExp("\\p{Cc}", "u").test(v.replace(/[\n\t]/gu, "")) && v.split("\n").length <= lines && new TextEncoder().encode(v).length <= bytes;
|
|
45572
45782
|
function assertProjectNotesReceipt(v) {
|
|
45573
|
-
if (!
|
|
45783
|
+
if (!record6(v) || Object.keys(v).sort().join(",") !== "updated_at,version" || !version(v["version"]) || v["version"] === 0 || !timestamp4(v["updated_at"]))
|
|
45574
45784
|
throw new TypeError("Invalid project notes receipt");
|
|
45575
45785
|
}
|
|
45576
45786
|
function assertProjectContext(v) {
|
|
45577
|
-
if (!
|
|
45787
|
+
if (!record6(v) || Object.keys(v).sort().join(",") !== "credit_access,generated_at,markdown,notes,project_id" || typeof v["project_id"] !== "string" || !/^[0-7][0-9A-HJKMNP-TV-Z]{25}$/u.test(v["project_id"]) || !timestamp4(v["generated_at"]) || !["included", "not_authorized"].includes(String(v["credit_access"])) || !bounded(v["markdown"], 500, 32768))
|
|
45578
45788
|
throw new TypeError("Invalid project context");
|
|
45579
45789
|
const notes = v["notes"];
|
|
45580
|
-
if (!
|
|
45790
|
+
if (!record6(notes) || Object.keys(notes).sort().join(",") !== "markdown,updated_at,version" || !version(notes["version"]) || !bounded(notes["markdown"], 250, 16384) || (notes["version"] === 0 ? notes["updated_at"] !== null || notes["markdown"] !== "" : !timestamp4(notes["updated_at"])))
|
|
45581
45791
|
throw new TypeError("Invalid project notes");
|
|
45582
45792
|
}
|
|
45583
45793
|
|
|
45584
45794
|
// packages/contracts/dist/project-exports.js
|
|
45585
45795
|
function assertProjectExport(value) {
|
|
45586
|
-
if (!
|
|
45796
|
+
if (!record7(value) || Object.keys(value).sort().join(",") !== "archive,error,id,next_poll_after_seconds,next_request_at,project_id,requested_at,state" || typeof value["id"] !== "string" || !id.test(value["id"]) || typeof value["project_id"] !== "string" || !id.test(value["project_id"]) || !["queued", "running", "succeeded", "failed", "cancelled"].includes(String(value["state"])) || !timestamp5(value["requested_at"]) || !timestamp5(value["next_request_at"]))
|
|
45587
45797
|
invalid4();
|
|
45588
45798
|
const active = value["state"] === "queued" || value["state"] === "running";
|
|
45589
45799
|
if (value["next_poll_after_seconds"] !== (active ? 5 : null))
|
|
45590
45800
|
invalid4();
|
|
45591
45801
|
if (value["state"] === "failed") {
|
|
45592
45802
|
const error = value["error"];
|
|
45593
|
-
if (!
|
|
45803
|
+
if (!record7(error) || Object.keys(error).sort().join(",") !== "code,message,retryable,suggested_action" || typeof error["code"] !== "string")
|
|
45594
45804
|
invalid4();
|
|
45595
45805
|
const expected = publicOperationFailure(error["code"]);
|
|
45596
45806
|
for (const key of Object.keys(expected))
|
|
@@ -45604,7 +45814,7 @@ function assertProjectExport(value) {
|
|
|
45604
45814
|
invalid4();
|
|
45605
45815
|
return;
|
|
45606
45816
|
}
|
|
45607
|
-
if (value["state"] !== "succeeded" || !
|
|
45817
|
+
if (value["state"] !== "succeeded" || !record7(archive) || Object.keys(archive).sort().join(",") !== "bytes,captured_at,download_expires_at,download_url,expires_at,sha256,sql_files" || !Number.isSafeInteger(archive["bytes"]) || Number(archive["bytes"]) < 1 || Number(archive["bytes"]) > 536870912 || typeof archive["sha256"] !== "string" || !/^sha256:[a-f0-9]{64}$/u.test(archive["sha256"]) || !['["dev.sql"]', '["prod.sql"]', '["dev.sql","prod.sql"]', '["shared.sql"]'].includes(JSON.stringify(archive["sql_files"])) || !timestamp5(archive["captured_at"]) || !timestamp5(archive["expires_at"]))
|
|
45608
45818
|
invalid4();
|
|
45609
45819
|
if (archive["download_url"] === null) {
|
|
45610
45820
|
if (archive["download_expires_at"] !== null)
|
|
@@ -45623,7 +45833,7 @@ function assertProjectExport(value) {
|
|
|
45623
45833
|
invalid4();
|
|
45624
45834
|
}
|
|
45625
45835
|
var id = /^[0-7][0-9A-HJKMNP-TV-Z]{25}$/u;
|
|
45626
|
-
function
|
|
45836
|
+
function record7(value) {
|
|
45627
45837
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
45628
45838
|
}
|
|
45629
45839
|
function timestamp5(value) {
|
|
@@ -45866,6 +46076,7 @@ var HELP_USAGE = Object.freeze({
|
|
|
45866
46076
|
"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
46077
|
"database watch list": "ohmyhost database watch list --project ULID [--environment dev|prod] --json (dev when omitted; a sleeping database wakes)",
|
|
45868
46078
|
"database watch delete": "ohmyhost database watch delete --project ULID --environment dev|prod --watch ID --idempotency-key KEY --yes --json",
|
|
46079
|
+
"database table create": "ohmyhost database table create --project ULID --environment dev|prod --table NAME --columns-file PATH [--primary-key COL[,COL]] --idempotency-key KEY --yes --json (the table is created in the public schema as the migration role, with the same access as migration tables, so a database watch can attach later; the columns file is a UTF-8 JSON array of 1 to 64 column objects, at most 64 KiB, each with name, type and optional nullable, identity and default; types: text, integer, bigint, boolean, numeric, double precision, timestamptz, date, uuid, jsonb; identity needs integer or bigint; default now needs timestamptz and default uuid needs uuid; identical repeats answer created false; at most 100 tables, 64 columns per table)",
|
|
45869
46080
|
"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)",
|
|
45870
46081
|
"database webhook list": "ohmyhost database webhook list --project ULID [--environment dev|prod] --json (dev when omitted; the secret is never listed)",
|
|
45871
46082
|
"database webhook get": "ohmyhost database webhook get --project ULID [--environment dev|prod] --webhook ID --json",
|
|
@@ -45991,6 +46202,7 @@ var LOGOUT_UNCONFIRMED_ACTION = "The saved login was removed from this computer,
|
|
|
45991
46202
|
var HEADERS_FILE_INVALID_ACTION = "Put one JSON object of header names and values in the file named by --headers-file: UTF-8, at most 8 KiB, unique names, values of visible ASCII characters. Names such as content-type, host, content-length, connection, transfer-encoding, user-agent, te, upgrade and expect, and names starting with pgcf-, cf- or x-forwarded-, are refused. Nothing was sent; fix the file and run the command again.";
|
|
45992
46203
|
var SCHEDULE_STATEMENTS_FILE_INVALID_ACTION = "Put one JSON array of 1 to 20 non-empty SQL strings in the file named by --statements-file: UTF-8, at most 64 KiB in total and 16 KiB per statement, without NUL characters. Nothing was saved; fix the file and run the command again.";
|
|
45993
46204
|
var SCHEDULE_INVALID_ACTION = "Check the schedule request: --cron takes five fields in UTC (9 to 120 characters), or --every-seconds takes 60 to 2678400, never both; --timeout-ms takes 1000 to 30000; the statements file must hold 1 to 20 non-blank SQL strings of at most 16 KiB each and 64 KiB in total. Nothing was saved; fix it and run the command again.";
|
|
46205
|
+
var COLUMNS_FILE_INVALID_ACTION = "Put one JSON array of 1 to 64 column objects in the file named by --columns-file: UTF-8, at most 64 KiB, each with a lower-case name, a type (text, integer, bigint, boolean, numeric, double precision, timestamptz, date, uuid or jsonb) and optional nullable, identity (integer or bigint only) and default (now for timestamptz, uuid for uuid). Each --primary-key column must be one of them, at most 8 names. Nothing was created; fix the file or the flags and run the command again.";
|
|
45994
46206
|
var STATEMENT_FILE_INVALID_ACTION = "Put one INSERT, UPDATE or DELETE statement that starts with that keyword (no leading comment or WITH), UTF-8, at most 64 KiB, in the file named by --statement-file, then rerun with the same --idempotency-key.";
|
|
45995
46207
|
var signInCommand = (commandPrefix, profile) => profile === void 0 ? `${commandPrefix} login --json` : `${commandPrefix} login${profile.organizationId === null ? "" : ` --organization ${profile.organizationId}`} --user ${profile.userId} --profile-name ${profile.name} --json`;
|
|
45996
46208
|
var endedLoginAction = (commandPrefix, profile) => `The sign-in of ${profile === void 0 ? "this computer's saved login" : `saved login ${profile.name} (user ${profile.userId}${profile.organizationId === null ? "" : `, organization ${profile.organizationId}`})`} ended and it was removed. Run '${signInCommand(commandPrefix, profile)}' to sign it in again.`;
|
|
@@ -46363,6 +46575,8 @@ var ProductCli = class {
|
|
|
46363
46575
|
return await this.listDatabaseWatches(command, signal);
|
|
46364
46576
|
if (command.kind === "database-watch-delete")
|
|
46365
46577
|
return await this.deleteDatabaseWatch(command, signal);
|
|
46578
|
+
if (command.kind === "database-table-create")
|
|
46579
|
+
return await this.createDatabaseTable(command, signal);
|
|
46366
46580
|
if (command.kind === "database-webhook-create")
|
|
46367
46581
|
return await this.createDatabaseWebhook(command, signal);
|
|
46368
46582
|
if (command.kind === "database-webhook-list")
|
|
@@ -46927,6 +47141,18 @@ var ProductCli = class {
|
|
|
46927
47141
|
});
|
|
46928
47142
|
return success("database watch delete", { status: "succeeded", deleted });
|
|
46929
47143
|
}
|
|
47144
|
+
/** The columns file and the key are checked before any request; a repeat answers the same table with created false. */
|
|
47145
|
+
async createDatabaseTable(command, signal) {
|
|
47146
|
+
const request = await tableCreateRequest(command);
|
|
47147
|
+
const api = await this.authenticatedApi(command.credentialStore, signal);
|
|
47148
|
+
const answer = await api.createProjectDatabaseTable({
|
|
47149
|
+
projectId: command.projectId,
|
|
47150
|
+
environment: command.environment,
|
|
47151
|
+
idempotencyKey: command.idempotencyKey,
|
|
47152
|
+
request
|
|
47153
|
+
});
|
|
47154
|
+
return success("database table create", { status: "succeeded", table: answer.table });
|
|
47155
|
+
}
|
|
46930
47156
|
/** The signing secret is returned by create only; every other answer carries no secret. */
|
|
46931
47157
|
async createDatabaseWebhook(command, signal) {
|
|
46932
47158
|
const request = await webhookCreateRequest(command);
|
|
@@ -47818,6 +48044,37 @@ var scheduleSetRequest = async (command) => {
|
|
|
47818
48044
|
throw new ProductCliFailure(2, "schedule_invalid", false, SCHEDULE_INVALID_ACTION);
|
|
47819
48045
|
}
|
|
47820
48046
|
};
|
|
48047
|
+
var tableCreateRequest = async (command) => {
|
|
48048
|
+
const columnsFailure = () => new ProductCliFailure(2, "columns_file_invalid", false, COLUMNS_FILE_INVALID_ACTION);
|
|
48049
|
+
const columns = await readBoundedUtf8File(command.columnsFile, 65536, columnsFailure).then((text) => {
|
|
48050
|
+
try {
|
|
48051
|
+
return JSON.parse(text);
|
|
48052
|
+
} catch {
|
|
48053
|
+
throw columnsFailure();
|
|
48054
|
+
}
|
|
48055
|
+
});
|
|
48056
|
+
try {
|
|
48057
|
+
const parsed = parseDatabaseTableCreateRequest({
|
|
48058
|
+
table: command.table,
|
|
48059
|
+
columns,
|
|
48060
|
+
...command.primaryKey.length === 0 ? {} : { primaryKey: command.primaryKey }
|
|
48061
|
+
});
|
|
48062
|
+
return {
|
|
48063
|
+
table: parsed.table,
|
|
48064
|
+
columns: parsed.columns.map(tableColumnInput),
|
|
48065
|
+
primaryKey: parsed.primaryKey
|
|
48066
|
+
};
|
|
48067
|
+
} catch {
|
|
48068
|
+
throw columnsFailure();
|
|
48069
|
+
}
|
|
48070
|
+
};
|
|
48071
|
+
var tableColumnInput = (column) => ({
|
|
48072
|
+
name: column.name,
|
|
48073
|
+
type: column.type,
|
|
48074
|
+
nullable: column.nullable,
|
|
48075
|
+
identity: column.identity,
|
|
48076
|
+
...column.default === null ? {} : { default: column.default }
|
|
48077
|
+
});
|
|
47821
48078
|
var psqlUnavailable = () => failure("database psql", 9, "psql_unavailable", false, "Install the PostgreSQL client (psql) and make it available on PATH, or run 'ohmyhost database access create' and connect with your own SQL client.");
|
|
47822
48079
|
var success = (command, body) => ({
|
|
47823
48080
|
exitCode: 0,
|
|
@@ -47963,6 +48220,8 @@ var parsedCommandName = (command) => {
|
|
|
47963
48220
|
return "database watch list";
|
|
47964
48221
|
if (command.kind === "database-watch-delete")
|
|
47965
48222
|
return "database watch delete";
|
|
48223
|
+
if (command.kind === "database-table-create")
|
|
48224
|
+
return "database table create";
|
|
47966
48225
|
if (command.kind === "database-webhook-create")
|
|
47967
48226
|
return "database webhook create";
|
|
47968
48227
|
if (command.kind === "database-webhook-list")
|
|
@@ -48185,12 +48444,12 @@ function buildClientParams(args, fields) {
|
|
|
48185
48444
|
};
|
|
48186
48445
|
const map = buildKeyMap(fields);
|
|
48187
48446
|
function writeSlot(slot, key, value) {
|
|
48188
|
-
let
|
|
48189
|
-
if (
|
|
48190
|
-
|
|
48191
|
-
params[slot] =
|
|
48447
|
+
let record8 = params[slot];
|
|
48448
|
+
if (record8 === void 0) {
|
|
48449
|
+
record8 = /* @__PURE__ */ Object.create(null);
|
|
48450
|
+
params[slot] = record8;
|
|
48192
48451
|
}
|
|
48193
|
-
|
|
48452
|
+
record8[key] = value;
|
|
48194
48453
|
}
|
|
48195
48454
|
let config;
|
|
48196
48455
|
for (const [index, arg] of args.entries()) {
|
|
@@ -50835,6 +51094,30 @@ var revokeProjectDatabaseAccess = (parameters, options) => {
|
|
|
50835
51094
|
...params
|
|
50836
51095
|
});
|
|
50837
51096
|
};
|
|
51097
|
+
var createProjectDatabaseTable = (parameters, options) => {
|
|
51098
|
+
const params = buildClientParams([parameters], [
|
|
51099
|
+
{
|
|
51100
|
+
args: [
|
|
51101
|
+
{ in: "headers", key: "X-Request-Id" },
|
|
51102
|
+
{ in: "headers", key: "Idempotency-Key" },
|
|
51103
|
+
{ in: "path", key: "project_id" },
|
|
51104
|
+
{ key: "databaseTableCreateRequest", map: "body" }
|
|
51105
|
+
]
|
|
51106
|
+
}
|
|
51107
|
+
]);
|
|
51108
|
+
return (options?.client ?? client).post({
|
|
51109
|
+
responseStyle: "data",
|
|
51110
|
+
security: [{ scheme: "bearer", type: "http" }],
|
|
51111
|
+
url: "/v1/projects/{project_id}/database/tables",
|
|
51112
|
+
...options,
|
|
51113
|
+
...params,
|
|
51114
|
+
headers: {
|
|
51115
|
+
"Content-Type": "application/json",
|
|
51116
|
+
...options?.headers,
|
|
51117
|
+
...params.headers
|
|
51118
|
+
}
|
|
51119
|
+
});
|
|
51120
|
+
};
|
|
50838
51121
|
var listProjectDatabaseWatches = (parameters, options) => {
|
|
50839
51122
|
const params = buildClientParams([parameters], [
|
|
50840
51123
|
{
|
|
@@ -52271,7 +52554,24 @@ function checkedResponse(kind, value) {
|
|
|
52271
52554
|
// apps/product-cli/dist/product-api.js
|
|
52272
52555
|
var WEBHOOK_SCOPE_MISMATCH = "Webhook response scope mismatch";
|
|
52273
52556
|
var WATCH_SCOPE_MISMATCH = "Watch response scope mismatch";
|
|
52557
|
+
var TABLE_SCOPE_MISMATCH = "Table response scope mismatch";
|
|
52274
52558
|
var SCHEDULE_SCOPE_MISMATCH = "Schedule response scope mismatch";
|
|
52559
|
+
function assertDatabaseTableAnswer(value) {
|
|
52560
|
+
const table = isRecordValue(value) ? value["table"] : void 0;
|
|
52561
|
+
const columns = isRecordValue(table) ? table["columns"] : void 0;
|
|
52562
|
+
const primaryKey = isRecordValue(table) ? table["primary_key"] : void 0;
|
|
52563
|
+
if (!isRecordValue(table) || !hasExactKeys(table, ["environment", "schema", "table", "columns", "primary_key", "created"]) || table["environment"] !== "dev" && table["environment"] !== "prod" || table["schema"] !== "public" || !isDatabaseTableIdentifier(table["table"]) || typeof table["created"] !== "boolean" || !Array.isArray(columns) || columns.length < 1 || !columns.every(isDatabaseTableAnswerColumn) || !Array.isArray(primaryKey) || !primaryKey.every((name) => columns.some((column) => column["name"] === name)))
|
|
52564
|
+
throw new TypeError("Invalid database table answer");
|
|
52565
|
+
}
|
|
52566
|
+
function isDatabaseTableAnswerColumn(value) {
|
|
52567
|
+
return isRecordValue(value) && hasExactKeys(value, ["name", "type", "nullable", "identity", "default"]) && isDatabaseTableIdentifier(value["name"]) && DATABASE_TABLE_COLUMN_TYPES.includes(value["type"]) && typeof value["nullable"] === "boolean" && typeof value["identity"] === "boolean" && (value["default"] === null || DATABASE_TABLE_DEFAULTS.includes(value["default"]));
|
|
52568
|
+
}
|
|
52569
|
+
function isRecordValue(value) {
|
|
52570
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
52571
|
+
}
|
|
52572
|
+
function hasExactKeys(value, keys) {
|
|
52573
|
+
return Object.keys(value).sort().join(",") === [...keys].sort().join(",");
|
|
52574
|
+
}
|
|
52275
52575
|
var GeneratedSdkProductApi = class {
|
|
52276
52576
|
#client;
|
|
52277
52577
|
managedSource;
|
|
@@ -52504,6 +52804,22 @@ var GeneratedSdkProductApi = class {
|
|
|
52504
52804
|
throw new TypeError(WATCH_SCOPE_MISMATCH);
|
|
52505
52805
|
return value;
|
|
52506
52806
|
}
|
|
52807
|
+
async createProjectDatabaseTable(input) {
|
|
52808
|
+
const value = await createProjectDatabaseTable({
|
|
52809
|
+
project_id: input.projectId,
|
|
52810
|
+
"Idempotency-Key": input.idempotencyKey,
|
|
52811
|
+
databaseTableCreateRequest: {
|
|
52812
|
+
environment: input.environment,
|
|
52813
|
+
table: input.request.table,
|
|
52814
|
+
columns: [...input.request.columns],
|
|
52815
|
+
...input.request.primaryKey.length === 0 ? {} : { primary_key: [...input.request.primaryKey] }
|
|
52816
|
+
}
|
|
52817
|
+
}, { client: this.#client });
|
|
52818
|
+
assertDatabaseTableAnswer(value);
|
|
52819
|
+
if (value.table.environment !== input.environment || value.table.table !== input.request.table)
|
|
52820
|
+
throw new TypeError(TABLE_SCOPE_MISMATCH);
|
|
52821
|
+
return value;
|
|
52822
|
+
}
|
|
52507
52823
|
/** The signing secret exists only in this answer; the CLI prints it once and stores nothing. */
|
|
52508
52824
|
async createProjectDatabaseWebhook(input) {
|
|
52509
52825
|
const value = await createProjectDatabaseWebhook({
|
|
@@ -54110,8 +54426,8 @@ function pnpmLockedVersion(document2, packageName) {
|
|
|
54110
54426
|
}
|
|
54111
54427
|
return null;
|
|
54112
54428
|
}
|
|
54113
|
-
function ownValue(
|
|
54114
|
-
return isRecord4(
|
|
54429
|
+
function ownValue(record8, key) {
|
|
54430
|
+
return isRecord4(record8) && Object.hasOwn(record8, key) ? record8[key] : void 0;
|
|
54115
54431
|
}
|
|
54116
54432
|
function isRecord4(value) {
|
|
54117
54433
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -57447,6 +57763,7 @@ export {
|
|
|
57447
57763
|
ACCOUNT_SENSITIVE_PROBLEMS,
|
|
57448
57764
|
classifyCliFailure,
|
|
57449
57765
|
GeneratedSdkManagedSourceApi,
|
|
57766
|
+
assertDatabaseTableAnswer,
|
|
57450
57767
|
GeneratedSdkProductApi,
|
|
57451
57768
|
RepositoryInitError,
|
|
57452
57769
|
RepositoryInitBlockedError,
|