@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
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
/** Column types a created table may declare; the closed list keeps type text out of the DDL. */
|
|
2
|
+
export const DATABASE_TABLE_COLUMN_TYPES = [
|
|
3
|
+
"text",
|
|
4
|
+
"integer",
|
|
5
|
+
"bigint",
|
|
6
|
+
"boolean",
|
|
7
|
+
"numeric",
|
|
8
|
+
"double precision",
|
|
9
|
+
"timestamptz",
|
|
10
|
+
"date",
|
|
11
|
+
"uuid",
|
|
12
|
+
"jsonb",
|
|
13
|
+
] as const;
|
|
14
|
+
export type DatabaseTableColumnType = (typeof DATABASE_TABLE_COLUMN_TYPES)[number];
|
|
15
|
+
/** `now` is DEFAULT now() on timestamptz; `uuid` is DEFAULT gen_random_uuid() on uuid. */
|
|
16
|
+
export const DATABASE_TABLE_DEFAULTS = ["now", "uuid"] as const;
|
|
17
|
+
export type DatabaseTableDefault = (typeof DATABASE_TABLE_DEFAULTS)[number];
|
|
18
|
+
export const DATABASE_TABLE_MAX_COLUMNS = 64;
|
|
19
|
+
export const DATABASE_TABLE_MAX_PRIMARY_KEY_COLUMNS = 8;
|
|
20
|
+
/** Ordinary and partitioned tables that a database may hold in its public schema. */
|
|
21
|
+
export const DATABASE_TABLE_LIMIT = 100;
|
|
22
|
+
export const DATABASE_TABLE_SCHEMA = "public";
|
|
23
|
+
|
|
24
|
+
const DATABASE_TABLE_IDENTIFIER_PATTERN = /^[a-z_][a-z0-9_]{0,62}$/u;
|
|
25
|
+
/** PostgreSQL reserved words: a table or column of such a name would need quoting everywhere it is used. */
|
|
26
|
+
const RESERVED_WORDS: ReadonlySet<string> = new Set([
|
|
27
|
+
"all",
|
|
28
|
+
"analyse",
|
|
29
|
+
"analyze",
|
|
30
|
+
"and",
|
|
31
|
+
"any",
|
|
32
|
+
"array",
|
|
33
|
+
"as",
|
|
34
|
+
"asc",
|
|
35
|
+
"asymmetric",
|
|
36
|
+
"both",
|
|
37
|
+
"case",
|
|
38
|
+
"cast",
|
|
39
|
+
"check",
|
|
40
|
+
"collate",
|
|
41
|
+
"column",
|
|
42
|
+
"constraint",
|
|
43
|
+
"create",
|
|
44
|
+
"current_catalog",
|
|
45
|
+
"current_date",
|
|
46
|
+
"current_role",
|
|
47
|
+
"current_time",
|
|
48
|
+
"current_timestamp",
|
|
49
|
+
"current_user",
|
|
50
|
+
"default",
|
|
51
|
+
"deferrable",
|
|
52
|
+
"desc",
|
|
53
|
+
"distinct",
|
|
54
|
+
"do",
|
|
55
|
+
"else",
|
|
56
|
+
"end",
|
|
57
|
+
"except",
|
|
58
|
+
"false",
|
|
59
|
+
"fetch",
|
|
60
|
+
"for",
|
|
61
|
+
"foreign",
|
|
62
|
+
"from",
|
|
63
|
+
"grant",
|
|
64
|
+
"group",
|
|
65
|
+
"having",
|
|
66
|
+
"in",
|
|
67
|
+
"initially",
|
|
68
|
+
"intersect",
|
|
69
|
+
"into",
|
|
70
|
+
"lateral",
|
|
71
|
+
"leading",
|
|
72
|
+
"limit",
|
|
73
|
+
"localtime",
|
|
74
|
+
"localtimestamp",
|
|
75
|
+
"not",
|
|
76
|
+
"null",
|
|
77
|
+
"offset",
|
|
78
|
+
"on",
|
|
79
|
+
"only",
|
|
80
|
+
"or",
|
|
81
|
+
"order",
|
|
82
|
+
"placing",
|
|
83
|
+
"primary",
|
|
84
|
+
"references",
|
|
85
|
+
"returning",
|
|
86
|
+
"select",
|
|
87
|
+
"session_user",
|
|
88
|
+
"some",
|
|
89
|
+
"symmetric",
|
|
90
|
+
"table",
|
|
91
|
+
"then",
|
|
92
|
+
"to",
|
|
93
|
+
"trailing",
|
|
94
|
+
"true",
|
|
95
|
+
"union",
|
|
96
|
+
"unique",
|
|
97
|
+
"user",
|
|
98
|
+
"using",
|
|
99
|
+
"variadic",
|
|
100
|
+
"when",
|
|
101
|
+
"where",
|
|
102
|
+
"window",
|
|
103
|
+
"with",
|
|
104
|
+
]);
|
|
105
|
+
|
|
106
|
+
export interface DatabaseTableColumn {
|
|
107
|
+
readonly name: string;
|
|
108
|
+
readonly type: DatabaseTableColumnType;
|
|
109
|
+
readonly nullable: boolean;
|
|
110
|
+
readonly identity: boolean;
|
|
111
|
+
readonly default: DatabaseTableDefault | null;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/** A create request after parsing: nullable is concrete and primaryKey is empty when the request names none. */
|
|
115
|
+
export interface DatabaseTableRequest {
|
|
116
|
+
readonly table: string;
|
|
117
|
+
readonly columns: readonly DatabaseTableColumn[];
|
|
118
|
+
readonly primaryKey: readonly string[];
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export interface DatabaseTable {
|
|
122
|
+
readonly schema: typeof DATABASE_TABLE_SCHEMA;
|
|
123
|
+
readonly table: string;
|
|
124
|
+
readonly columns: readonly DatabaseTableColumn[];
|
|
125
|
+
readonly primaryKey: readonly string[];
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export interface DatabaseTableCreated {
|
|
129
|
+
readonly table: DatabaseTable;
|
|
130
|
+
readonly created: boolean;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
interface ColumnInput {
|
|
134
|
+
readonly name: string;
|
|
135
|
+
readonly type: DatabaseTableColumnType;
|
|
136
|
+
readonly nullable: boolean | undefined;
|
|
137
|
+
readonly identity: boolean;
|
|
138
|
+
readonly default: DatabaseTableDefault | null;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/** Identifiers are plain lower-case SQL names; the renderer quotes them and no other caller text reaches the DDL. */
|
|
142
|
+
export function isDatabaseTableIdentifier(value: unknown): value is string {
|
|
143
|
+
return (
|
|
144
|
+
typeof value === "string" &&
|
|
145
|
+
DATABASE_TABLE_IDENTIFIER_PATTERN.test(value) &&
|
|
146
|
+
!value.startsWith("pg_") &&
|
|
147
|
+
!RESERVED_WORDS.has(value)
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export function parseDatabaseTableCreateRequest(value: unknown): DatabaseTableRequest {
|
|
152
|
+
if (
|
|
153
|
+
!record(value) ||
|
|
154
|
+
!onlyKeys(value, ["table", "columns", "primaryKey"]) ||
|
|
155
|
+
!isDatabaseTableIdentifier(value["table"]) ||
|
|
156
|
+
!Array.isArray(value["columns"]) ||
|
|
157
|
+
value["columns"].length < 1 ||
|
|
158
|
+
value["columns"].length > DATABASE_TABLE_MAX_COLUMNS
|
|
159
|
+
)
|
|
160
|
+
throw new TypeError("Invalid database table request");
|
|
161
|
+
const inputs = value["columns"].map(parseColumn);
|
|
162
|
+
const names = inputs.map((column) => column.name);
|
|
163
|
+
if (new Set(names).size !== names.length || inputs.filter((column) => column.identity).length > 1)
|
|
164
|
+
throw new TypeError("Invalid database table request");
|
|
165
|
+
const primaryKey = parsePrimaryKey(value["primaryKey"], names);
|
|
166
|
+
return {
|
|
167
|
+
table: value["table"],
|
|
168
|
+
columns: inputs.map((column) => completeColumn(column, primaryKey.includes(column.name))),
|
|
169
|
+
primaryKey,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* The one CREATE TABLE statement of a request, in the public schema. Identifiers are validated again here, so the
|
|
175
|
+
* renderer is safe for any caller; the statement has no trailing semicolon.
|
|
176
|
+
*/
|
|
177
|
+
export function renderCreateTableStatement(request: DatabaseTableRequest): string {
|
|
178
|
+
const definitions = request.columns.map(renderColumn);
|
|
179
|
+
if (request.primaryKey.length > 0)
|
|
180
|
+
definitions.push(`PRIMARY KEY (${request.primaryKey.map(quoted).join(",")})`);
|
|
181
|
+
return `CREATE TABLE ${databaseTableReference(request.table)} (${definitions.join(", ")})`;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/** The quoted, schema-qualified name of a table of the public schema, as SQL statements use it. */
|
|
185
|
+
export function databaseTableReference(table: string): string {
|
|
186
|
+
return `${quoted(DATABASE_TABLE_SCHEMA)}.${quoted(table)}`;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export function assertDatabaseTableCreated(value: unknown): asserts value is DatabaseTableCreated {
|
|
190
|
+
if (
|
|
191
|
+
!record(value) ||
|
|
192
|
+
!exact(value, ["table", "created"]) ||
|
|
193
|
+
typeof value["created"] !== "boolean" ||
|
|
194
|
+
!isDatabaseTable(value["table"])
|
|
195
|
+
)
|
|
196
|
+
throw new TypeError("Invalid database table");
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function parseColumn(value: unknown): ColumnInput {
|
|
200
|
+
if (
|
|
201
|
+
!record(value) ||
|
|
202
|
+
!onlyKeys(value, ["name", "type", "nullable", "identity", "default"]) ||
|
|
203
|
+
!isDatabaseTableIdentifier(value["name"]) ||
|
|
204
|
+
!oneOf(DATABASE_TABLE_COLUMN_TYPES, value["type"]) ||
|
|
205
|
+
(value["nullable"] !== undefined && typeof value["nullable"] !== "boolean") ||
|
|
206
|
+
(value["identity"] !== undefined && typeof value["identity"] !== "boolean") ||
|
|
207
|
+
(value["default"] !== undefined && !oneOf(DATABASE_TABLE_DEFAULTS, value["default"]))
|
|
208
|
+
)
|
|
209
|
+
throw new TypeError("Invalid database table request");
|
|
210
|
+
const type = value["type"];
|
|
211
|
+
const identity = value["identity"] === true;
|
|
212
|
+
const defaultValue = value["default"] ?? null;
|
|
213
|
+
if (identity && type !== "integer" && type !== "bigint")
|
|
214
|
+
throw new TypeError("Invalid database table request");
|
|
215
|
+
if (identity && defaultValue !== null) throw new TypeError("Invalid database table request");
|
|
216
|
+
if (defaultValue === "now" && type !== "timestamptz")
|
|
217
|
+
throw new TypeError("Invalid database table request");
|
|
218
|
+
if (defaultValue === "uuid" && type !== "uuid")
|
|
219
|
+
throw new TypeError("Invalid database table request");
|
|
220
|
+
return {
|
|
221
|
+
name: value["name"],
|
|
222
|
+
type,
|
|
223
|
+
nullable: value["nullable"],
|
|
224
|
+
identity,
|
|
225
|
+
default: defaultValue,
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function parsePrimaryKey(value: unknown, names: readonly string[]): readonly string[] {
|
|
230
|
+
if (value === undefined) return [];
|
|
231
|
+
if (
|
|
232
|
+
!Array.isArray(value) ||
|
|
233
|
+
value.length < 1 ||
|
|
234
|
+
value.length > DATABASE_TABLE_MAX_PRIMARY_KEY_COLUMNS ||
|
|
235
|
+
new Set(value).size !== value.length ||
|
|
236
|
+
!value.every((name) => typeof name === "string" && names.includes(name))
|
|
237
|
+
)
|
|
238
|
+
throw new TypeError("Invalid database table request");
|
|
239
|
+
return value as string[];
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/** Identity and primary key columns are NOT NULL; asking for a nullable one of them is a contradiction. */
|
|
243
|
+
function completeColumn(column: ColumnInput, keyed: boolean): DatabaseTableColumn {
|
|
244
|
+
const required = column.identity || keyed;
|
|
245
|
+
if (required && column.nullable === true) throw new TypeError("Invalid database table request");
|
|
246
|
+
return {
|
|
247
|
+
name: column.name,
|
|
248
|
+
type: column.type,
|
|
249
|
+
nullable: required ? false : (column.nullable ?? true),
|
|
250
|
+
identity: column.identity,
|
|
251
|
+
default: column.default,
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
function renderColumn(column: DatabaseTableColumn): string {
|
|
256
|
+
if (!oneOf(DATABASE_TABLE_COLUMN_TYPES, column.type))
|
|
257
|
+
throw new TypeError("Invalid database table column type");
|
|
258
|
+
const parts = [quoted(column.name), column.type];
|
|
259
|
+
if (!column.nullable) parts.push("NOT NULL");
|
|
260
|
+
if (column.identity) parts.push("GENERATED ALWAYS AS IDENTITY");
|
|
261
|
+
if (column.default === "now") parts.push("DEFAULT now()");
|
|
262
|
+
if (column.default === "uuid") parts.push("DEFAULT gen_random_uuid()");
|
|
263
|
+
return parts.join(" ");
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
function quoted(identifier: string): string {
|
|
267
|
+
if (!isDatabaseTableIdentifier(identifier))
|
|
268
|
+
throw new TypeError("Invalid database table identifier");
|
|
269
|
+
return `"${identifier}"`;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
function isDatabaseTable(value: unknown): boolean {
|
|
273
|
+
if (!record(value) || !exact(value, ["schema", "table", "columns", "primaryKey"])) return false;
|
|
274
|
+
const columns = value["columns"];
|
|
275
|
+
const primaryKey = value["primaryKey"];
|
|
276
|
+
if (
|
|
277
|
+
value["schema"] !== DATABASE_TABLE_SCHEMA ||
|
|
278
|
+
!isDatabaseTableIdentifier(value["table"]) ||
|
|
279
|
+
!Array.isArray(columns) ||
|
|
280
|
+
columns.length < 1 ||
|
|
281
|
+
columns.length > DATABASE_TABLE_MAX_COLUMNS ||
|
|
282
|
+
!columns.every(isDatabaseTableColumn) ||
|
|
283
|
+
!Array.isArray(primaryKey) ||
|
|
284
|
+
primaryKey.length > DATABASE_TABLE_MAX_PRIMARY_KEY_COLUMNS
|
|
285
|
+
)
|
|
286
|
+
return false;
|
|
287
|
+
const names = columns.map((column) => column.name);
|
|
288
|
+
return primaryKey.every((name) => typeof name === "string" && names.includes(name));
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
function isDatabaseTableColumn(value: unknown): value is DatabaseTableColumn {
|
|
292
|
+
return (
|
|
293
|
+
record(value) &&
|
|
294
|
+
exact(value, ["name", "type", "nullable", "identity", "default"]) &&
|
|
295
|
+
isDatabaseTableIdentifier(value["name"]) &&
|
|
296
|
+
oneOf(DATABASE_TABLE_COLUMN_TYPES, value["type"]) &&
|
|
297
|
+
typeof value["nullable"] === "boolean" &&
|
|
298
|
+
typeof value["identity"] === "boolean" &&
|
|
299
|
+
(value["default"] === null || oneOf(DATABASE_TABLE_DEFAULTS, value["default"]))
|
|
300
|
+
);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
function oneOf<T extends string>(allowed: readonly T[], value: unknown): value is T {
|
|
304
|
+
return typeof value === "string" && (allowed as readonly string[]).includes(value);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
function record(value: unknown): value is Record<string, unknown> {
|
|
308
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
function onlyKeys(value: Record<string, unknown>, allowed: readonly string[]): boolean {
|
|
312
|
+
return Object.keys(value).every((key) => allowed.includes(key));
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
function exact(value: Record<string, unknown>, keys: readonly string[]): boolean {
|
|
316
|
+
return Object.keys(value).sort().join(",") === [...keys].sort().join(",");
|
|
317
|
+
}
|
|
@@ -227,6 +227,20 @@ export const PROBLEM_POLICY = {
|
|
|
227
227
|
"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.",
|
|
228
228
|
title: "Table already has a capture trigger",
|
|
229
229
|
},
|
|
230
|
+
database_table_conflict: {
|
|
231
|
+
status: 409,
|
|
232
|
+
retryable: false,
|
|
233
|
+
action:
|
|
234
|
+
"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.",
|
|
235
|
+
title: "Table already exists with another definition",
|
|
236
|
+
},
|
|
237
|
+
database_table_limit: {
|
|
238
|
+
status: 409,
|
|
239
|
+
retryable: false,
|
|
240
|
+
action:
|
|
241
|
+
"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.",
|
|
242
|
+
title: "Database table limit reached",
|
|
243
|
+
},
|
|
230
244
|
project_notes_conflict: {
|
|
231
245
|
status: 409,
|
|
232
246
|
retryable: false,
|
|
@@ -23,6 +23,7 @@ export {
|
|
|
23
23
|
createOrganization,
|
|
24
24
|
createProject,
|
|
25
25
|
createProjectDatabaseAccess,
|
|
26
|
+
createProjectDatabaseTable,
|
|
26
27
|
createProjectDatabaseWatch,
|
|
27
28
|
createProjectDatabaseWebhook,
|
|
28
29
|
createProjectDataChange,
|
|
@@ -274,6 +275,11 @@ export type {
|
|
|
274
275
|
CreateProjectDatabaseAccessErrors,
|
|
275
276
|
CreateProjectDatabaseAccessResponse,
|
|
276
277
|
CreateProjectDatabaseAccessResponses,
|
|
278
|
+
CreateProjectDatabaseTableData,
|
|
279
|
+
CreateProjectDatabaseTableError,
|
|
280
|
+
CreateProjectDatabaseTableErrors,
|
|
281
|
+
CreateProjectDatabaseTableResponse,
|
|
282
|
+
CreateProjectDatabaseTableResponses,
|
|
277
283
|
CreateProjectDatabaseWatchData,
|
|
278
284
|
CreateProjectDatabaseWatchError,
|
|
279
285
|
CreateProjectDatabaseWatchErrors,
|
|
@@ -333,6 +339,12 @@ export type {
|
|
|
333
339
|
DatabaseScheduleRunAccepted,
|
|
334
340
|
DatabaseScheduleRunPage,
|
|
335
341
|
DatabaseScheduleSetRequest,
|
|
342
|
+
DatabaseTable,
|
|
343
|
+
DatabaseTableColumn,
|
|
344
|
+
DatabaseTableColumnRequest,
|
|
345
|
+
DatabaseTableColumnType,
|
|
346
|
+
DatabaseTableCreated,
|
|
347
|
+
DatabaseTableCreateRequest,
|
|
336
348
|
DatabaseWatch,
|
|
337
349
|
DatabaseWatchCreateRequest,
|
|
338
350
|
DatabaseWatchDeleted,
|
|
@@ -60,6 +60,8 @@ import type {
|
|
|
60
60
|
CreateOrganizationResponses,
|
|
61
61
|
CreateProjectDatabaseAccessErrors,
|
|
62
62
|
CreateProjectDatabaseAccessResponses,
|
|
63
|
+
CreateProjectDatabaseTableErrors,
|
|
64
|
+
CreateProjectDatabaseTableResponses,
|
|
63
65
|
CreateProjectDatabaseWatchErrors,
|
|
64
66
|
CreateProjectDatabaseWatchResponses,
|
|
65
67
|
CreateProjectDatabaseWebhookErrors,
|
|
@@ -79,6 +81,7 @@ import type {
|
|
|
79
81
|
CreateWorkspaceMailDomainRequest,
|
|
80
82
|
CreateWorkspaceMailDomainResponses,
|
|
81
83
|
DatabaseScheduleSetRequest,
|
|
84
|
+
DatabaseTableCreateRequest,
|
|
82
85
|
DatabaseWatchCreateRequest,
|
|
83
86
|
DatabaseWebhookCreateRequest,
|
|
84
87
|
DeclareApplicationDomainIdentityErrors,
|
|
@@ -4766,6 +4769,57 @@ export const revokeProjectDatabaseAccess = <ThrowOnError extends boolean = true>
|
|
|
4766
4769
|
});
|
|
4767
4770
|
};
|
|
4768
4771
|
|
|
4772
|
+
/**
|
|
4773
|
+
* Create a table in the project's database
|
|
4774
|
+
*
|
|
4775
|
+
* Creates one ordinary table in the public schema of one environment's database, with the columns and the primary key the request names. Repeating an identical request answers the existing table with 200; a table of the same name with another definition is refused with database_table_conflict (409). The request wakes a sleeping database. A reached Stop budget refuses with project_budget_exceeded (402). At most 100 tables exist per database.
|
|
4776
|
+
*/
|
|
4777
|
+
export const createProjectDatabaseTable = <ThrowOnError extends boolean = true>(
|
|
4778
|
+
parameters: {
|
|
4779
|
+
"X-Request-Id"?: string;
|
|
4780
|
+
"Idempotency-Key": string;
|
|
4781
|
+
project_id: Ulid;
|
|
4782
|
+
databaseTableCreateRequest: DatabaseTableCreateRequest;
|
|
4783
|
+
},
|
|
4784
|
+
options?: Options<never, ThrowOnError>,
|
|
4785
|
+
): RequestResult<
|
|
4786
|
+
CreateProjectDatabaseTableResponses,
|
|
4787
|
+
CreateProjectDatabaseTableErrors,
|
|
4788
|
+
ThrowOnError,
|
|
4789
|
+
"data"
|
|
4790
|
+
> => {
|
|
4791
|
+
const params = buildClientParams(
|
|
4792
|
+
[parameters],
|
|
4793
|
+
[
|
|
4794
|
+
{
|
|
4795
|
+
args: [
|
|
4796
|
+
{ in: "headers", key: "X-Request-Id" },
|
|
4797
|
+
{ in: "headers", key: "Idempotency-Key" },
|
|
4798
|
+
{ in: "path", key: "project_id" },
|
|
4799
|
+
{ key: "databaseTableCreateRequest", map: "body" },
|
|
4800
|
+
],
|
|
4801
|
+
},
|
|
4802
|
+
],
|
|
4803
|
+
);
|
|
4804
|
+
return (options?.client ?? client).post<
|
|
4805
|
+
CreateProjectDatabaseTableResponses,
|
|
4806
|
+
CreateProjectDatabaseTableErrors,
|
|
4807
|
+
ThrowOnError,
|
|
4808
|
+
"data"
|
|
4809
|
+
>({
|
|
4810
|
+
responseStyle: "data",
|
|
4811
|
+
security: [{ scheme: "bearer", type: "http" }],
|
|
4812
|
+
url: "/v1/projects/{project_id}/database/tables",
|
|
4813
|
+
...options,
|
|
4814
|
+
...params,
|
|
4815
|
+
headers: {
|
|
4816
|
+
"Content-Type": "application/json",
|
|
4817
|
+
...options?.headers,
|
|
4818
|
+
...params.headers,
|
|
4819
|
+
},
|
|
4820
|
+
});
|
|
4821
|
+
};
|
|
4822
|
+
|
|
4769
4823
|
/**
|
|
4770
4824
|
* List the project's database watches
|
|
4771
4825
|
*
|
|
@@ -962,6 +962,75 @@ export type DatabaseWebhookEventType =
|
|
|
962
962
|
*/
|
|
963
963
|
export type DatabaseWebhookEventPattern = DatabaseWebhookEventType | string;
|
|
964
964
|
|
|
965
|
+
export type DatabaseTableCreateRequest = {
|
|
966
|
+
environment: "dev" | "prod";
|
|
967
|
+
/**
|
|
968
|
+
* Name of the new table in the public schema. Lower-case, not a PostgreSQL reserved word and not starting with pg_.
|
|
969
|
+
*/
|
|
970
|
+
table: string;
|
|
971
|
+
/**
|
|
972
|
+
* Columns in the order written. Names are unique, and at most one column is an identity column.
|
|
973
|
+
*/
|
|
974
|
+
columns: Array<DatabaseTableColumnRequest>;
|
|
975
|
+
/**
|
|
976
|
+
* Columns of the primary key, each one of the table's columns. Identity and primary key columns are NOT NULL; omitted when the table has no primary key.
|
|
977
|
+
*/
|
|
978
|
+
primary_key?: Array<string>;
|
|
979
|
+
};
|
|
980
|
+
|
|
981
|
+
export type DatabaseTableColumnRequest = {
|
|
982
|
+
name: string;
|
|
983
|
+
type: DatabaseTableColumnType;
|
|
984
|
+
/**
|
|
985
|
+
* Whether the column accepts NULL. Identity and primary key columns never do.
|
|
986
|
+
*/
|
|
987
|
+
nullable?: boolean;
|
|
988
|
+
/**
|
|
989
|
+
* Generated always as identity. Only integer and bigint columns can be identity columns, and an identity column has no default.
|
|
990
|
+
*/
|
|
991
|
+
identity?: boolean;
|
|
992
|
+
/**
|
|
993
|
+
* now is now() on a timestamptz column; uuid is gen_random_uuid() on a uuid column. Omitted when the column has no default.
|
|
994
|
+
*/
|
|
995
|
+
default?: "now" | "uuid";
|
|
996
|
+
};
|
|
997
|
+
|
|
998
|
+
export type DatabaseTableColumnType =
|
|
999
|
+
| "text"
|
|
1000
|
+
| "integer"
|
|
1001
|
+
| "bigint"
|
|
1002
|
+
| "boolean"
|
|
1003
|
+
| "numeric"
|
|
1004
|
+
| "double precision"
|
|
1005
|
+
| "timestamptz"
|
|
1006
|
+
| "date"
|
|
1007
|
+
| "uuid"
|
|
1008
|
+
| "jsonb";
|
|
1009
|
+
|
|
1010
|
+
export type DatabaseTableColumn = {
|
|
1011
|
+
name: string;
|
|
1012
|
+
type: DatabaseTableColumnType;
|
|
1013
|
+
nullable: boolean;
|
|
1014
|
+
identity: boolean;
|
|
1015
|
+
default: "now" | "uuid" | null;
|
|
1016
|
+
};
|
|
1017
|
+
|
|
1018
|
+
export type DatabaseTable = {
|
|
1019
|
+
environment: "dev" | "prod";
|
|
1020
|
+
schema: "public";
|
|
1021
|
+
table: string;
|
|
1022
|
+
columns: Array<DatabaseTableColumn>;
|
|
1023
|
+
primary_key: Array<string>;
|
|
1024
|
+
/**
|
|
1025
|
+
* true when this request created the table, false when an identical table already existed.
|
|
1026
|
+
*/
|
|
1027
|
+
created: boolean;
|
|
1028
|
+
};
|
|
1029
|
+
|
|
1030
|
+
export type DatabaseTableCreated = {
|
|
1031
|
+
table: DatabaseTable;
|
|
1032
|
+
};
|
|
1033
|
+
|
|
965
1034
|
export type DatabaseWatchCreateRequest = {
|
|
966
1035
|
environment: "dev" | "prod";
|
|
967
1036
|
/**
|
|
@@ -1661,6 +1730,8 @@ export type ProblemDetails = {
|
|
|
1661
1730
|
| "database_watch_column_unavailable"
|
|
1662
1731
|
| "database_watch_events_unavailable"
|
|
1663
1732
|
| "database_watch_conflict"
|
|
1733
|
+
| "database_table_conflict"
|
|
1734
|
+
| "database_table_limit"
|
|
1664
1735
|
| "compute_change_pending"
|
|
1665
1736
|
| "compute_change_conflict"
|
|
1666
1737
|
| "billing_purchase_conflict"
|
|
@@ -8182,6 +8253,76 @@ export type RevokeProjectDatabaseAccessResponses = {
|
|
|
8182
8253
|
export type RevokeProjectDatabaseAccessResponse =
|
|
8183
8254
|
RevokeProjectDatabaseAccessResponses[keyof RevokeProjectDatabaseAccessResponses];
|
|
8184
8255
|
|
|
8256
|
+
export type CreateProjectDatabaseTableData = {
|
|
8257
|
+
body: DatabaseTableCreateRequest;
|
|
8258
|
+
headers: {
|
|
8259
|
+
/**
|
|
8260
|
+
* Optional caller-provided correlation identifier.
|
|
8261
|
+
*/
|
|
8262
|
+
"X-Request-Id"?: string;
|
|
8263
|
+
/**
|
|
8264
|
+
* Identifies one mutation and its canonical request payload.
|
|
8265
|
+
*/
|
|
8266
|
+
"Idempotency-Key": string;
|
|
8267
|
+
};
|
|
8268
|
+
path: {
|
|
8269
|
+
/**
|
|
8270
|
+
* Project identifier.
|
|
8271
|
+
*/
|
|
8272
|
+
project_id: Ulid;
|
|
8273
|
+
};
|
|
8274
|
+
query?: never;
|
|
8275
|
+
url: "/v1/projects/{project_id}/database/tables";
|
|
8276
|
+
};
|
|
8277
|
+
|
|
8278
|
+
export type CreateProjectDatabaseTableErrors = {
|
|
8279
|
+
/**
|
|
8280
|
+
* The request failed.
|
|
8281
|
+
*/
|
|
8282
|
+
400: ProblemDetails;
|
|
8283
|
+
/**
|
|
8284
|
+
* The request failed.
|
|
8285
|
+
*/
|
|
8286
|
+
401: ProblemDetails;
|
|
8287
|
+
/**
|
|
8288
|
+
* The request failed.
|
|
8289
|
+
*/
|
|
8290
|
+
402: ProblemDetails;
|
|
8291
|
+
/**
|
|
8292
|
+
* The resource does not exist or is not visible to the authenticated principal.
|
|
8293
|
+
*/
|
|
8294
|
+
404: ProblemDetails;
|
|
8295
|
+
/**
|
|
8296
|
+
* The request failed.
|
|
8297
|
+
*/
|
|
8298
|
+
409: ProblemDetails;
|
|
8299
|
+
/**
|
|
8300
|
+
* The request failed.
|
|
8301
|
+
*/
|
|
8302
|
+
429: ProblemDetails;
|
|
8303
|
+
/**
|
|
8304
|
+
* The request failed.
|
|
8305
|
+
*/
|
|
8306
|
+
503: ProblemDetails;
|
|
8307
|
+
};
|
|
8308
|
+
|
|
8309
|
+
export type CreateProjectDatabaseTableError =
|
|
8310
|
+
CreateProjectDatabaseTableErrors[keyof CreateProjectDatabaseTableErrors];
|
|
8311
|
+
|
|
8312
|
+
export type CreateProjectDatabaseTableResponses = {
|
|
8313
|
+
/**
|
|
8314
|
+
* The table already exists with the same columns, types, nullability, identity, defaults and primary key.
|
|
8315
|
+
*/
|
|
8316
|
+
200: DatabaseTableCreated;
|
|
8317
|
+
/**
|
|
8318
|
+
* The table this request created.
|
|
8319
|
+
*/
|
|
8320
|
+
201: DatabaseTableCreated;
|
|
8321
|
+
};
|
|
8322
|
+
|
|
8323
|
+
export type CreateProjectDatabaseTableResponse =
|
|
8324
|
+
CreateProjectDatabaseTableResponses[keyof CreateProjectDatabaseTableResponses];
|
|
8325
|
+
|
|
8185
8326
|
export type ListProjectDatabaseWatchesData = {
|
|
8186
8327
|
body?: never;
|
|
8187
8328
|
headers?: {
|