@oneuptime/common 7.0.4358 → 7.0.4395
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/Models/AnalyticsModels/AnalyticsBaseModel/AnalyticsBaseModel.ts +0 -7
- package/Models/AnalyticsModels/AnalyticsBaseModel/CommonModel.ts +0 -13
- package/Models/AnalyticsModels/ExceptionInstance.ts +2 -2
- package/Models/DatabaseModels/Monitor.ts +1 -1
- package/Models/DatabaseModels/OnCallDutyPolicyEscalationRuleSchedule.ts +2 -2
- package/Models/DatabaseModels/OnCallDutyPolicyEscalationRuleTeam.ts +2 -2
- package/Models/DatabaseModels/OnCallDutyPolicyEscalationRuleUser.ts +2 -2
- package/Models/DatabaseModels/OnCallDutyPolicyTimeLog.ts +2 -2
- package/Models/DatabaseModels/Probe.ts +7 -1
- package/Models/DatabaseModels/ServiceCatalog.ts +2 -2
- package/Models/DatabaseModels/ServiceCopilotCodeRepository.ts +2 -2
- package/Server/Middleware/ProjectAuthorization.ts +11 -3
- package/Server/Services/OpenTelemetryIngestService.ts +13 -9
- package/Server/Utils/AnalyticsDatabase/Statement.ts +0 -1
- package/Server/Utils/AnalyticsDatabase/StatementGenerator.ts +28 -81
- package/Server/Utils/OpenAPI.ts +605 -16
- package/Server/Utils/StartServer.ts +2 -2
- package/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.ts +0 -49
- package/Types/AnalyticsDatabase/TableColumn.ts +0 -26
- package/Types/AnalyticsDatabase/TableColumnType.ts +2 -1
- package/Types/Database/TableColumnType.ts +3 -0
- package/Types/GenericFunction.ts +1 -1
- package/Types/GenericObject.ts +1 -1
- package/Types/Object.ts +1 -1
- package/UI/esbuild-config.js +214 -0
- package/Utils/Schema/AnalyticsModelSchema.ts +741 -0
- package/Utils/Schema/BaseSchema.ts +450 -0
- package/Utils/Schema/ModelSchema.ts +227 -460
- package/build/dist/Models/AnalyticsModels/AnalyticsBaseModel/AnalyticsBaseModel.js +0 -6
- package/build/dist/Models/AnalyticsModels/AnalyticsBaseModel/AnalyticsBaseModel.js.map +1 -1
- package/build/dist/Models/AnalyticsModels/AnalyticsBaseModel/CommonModel.js +0 -9
- package/build/dist/Models/AnalyticsModels/AnalyticsBaseModel/CommonModel.js.map +1 -1
- package/build/dist/Models/AnalyticsModels/ExceptionInstance.js +2 -2
- package/build/dist/Models/AnalyticsModels/ExceptionInstance.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Monitor.js +1 -1
- package/build/dist/Models/DatabaseModels/Monitor.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyEscalationRuleSchedule.js +2 -2
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyEscalationRuleSchedule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyEscalationRuleTeam.js +2 -2
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyEscalationRuleTeam.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyEscalationRuleUser.js +2 -2
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyEscalationRuleUser.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyTimeLog.js +2 -2
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyTimeLog.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Probe.js +7 -1
- package/build/dist/Models/DatabaseModels/Probe.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ServiceCatalog.js +2 -2
- package/build/dist/Models/DatabaseModels/ServiceCatalog.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ServiceCopilotCodeRepository.js +2 -2
- package/build/dist/Models/DatabaseModels/ServiceCopilotCodeRepository.js.map +1 -1
- package/build/dist/Server/Middleware/ProjectAuthorization.js +7 -3
- package/build/dist/Server/Middleware/ProjectAuthorization.js.map +1 -1
- package/build/dist/Server/Services/OpenTelemetryIngestService.js +8 -4
- package/build/dist/Server/Services/OpenTelemetryIngestService.js.map +1 -1
- package/build/dist/Server/Utils/AnalyticsDatabase/Statement.js +0 -1
- package/build/dist/Server/Utils/AnalyticsDatabase/Statement.js.map +1 -1
- package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js +15 -55
- package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js.map +1 -1
- package/build/dist/Server/Utils/OpenAPI.js +467 -12
- package/build/dist/Server/Utils/OpenAPI.js.map +1 -1
- package/build/dist/Server/Utils/StartServer.js +2 -2
- package/build/dist/Server/Utils/StartServer.js.map +1 -1
- package/build/dist/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.js +0 -43
- package/build/dist/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.js.map +1 -1
- package/build/dist/Types/AnalyticsDatabase/TableColumn.js +0 -19
- package/build/dist/Types/AnalyticsDatabase/TableColumn.js.map +1 -1
- package/build/dist/Types/AnalyticsDatabase/TableColumnType.js +2 -1
- package/build/dist/Types/AnalyticsDatabase/TableColumnType.js.map +1 -1
- package/build/dist/Types/Database/TableColumnType.js +3 -0
- package/build/dist/Types/Database/TableColumnType.js.map +1 -1
- package/build/dist/Utils/Schema/AnalyticsModelSchema.js +619 -0
- package/build/dist/Utils/Schema/AnalyticsModelSchema.js.map +1 -0
- package/build/dist/Utils/Schema/BaseSchema.js +295 -0
- package/build/dist/Utils/Schema/BaseSchema.js.map +1 -0
- package/build/dist/Utils/Schema/ModelSchema.js +207 -390
- package/build/dist/Utils/Schema/ModelSchema.js.map +1 -1
- package/package.json +3 -1
- package/Models/AnalyticsModels/AnalyticsBaseModel/NestedModel.ts +0 -8
- package/Models/AnalyticsModels/NestedModels/KeyValueNestedModel.ts +0 -59
- package/build/dist/Models/AnalyticsModels/AnalyticsBaseModel/NestedModel.js +0 -7
- package/build/dist/Models/AnalyticsModels/AnalyticsBaseModel/NestedModel.js.map +0 -1
- package/build/dist/Models/AnalyticsModels/NestedModels/KeyValueNestedModel.js +0 -51
- package/build/dist/Models/AnalyticsModels/NestedModels/KeyValueNestedModel.js.map +0 -1
|
@@ -6,42 +6,31 @@ import {
|
|
|
6
6
|
} from "../../Types/Database/TableColumn";
|
|
7
7
|
import Dictionary from "../../Types/Dictionary";
|
|
8
8
|
import DatabaseBaseModel from "../../Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel";
|
|
9
|
-
import SortOrder from "../../Types/BaseDatabase/SortOrder";
|
|
10
9
|
import logger from "../../Server/Utils/Logger";
|
|
11
10
|
import Color from "../../Types/Color";
|
|
12
11
|
import { z as ZodTypes } from "zod";
|
|
13
12
|
import BadDataException from "../../Types/Exception/BadDataException";
|
|
14
13
|
import Permission, { PermissionHelper } from "../../Types/Permission";
|
|
15
14
|
import { ColumnAccessControl } from "../../Types/BaseDatabase/AccessControl";
|
|
15
|
+
import { BaseSchema, SchemaExample, ShapeRecord } from "./BaseSchema";
|
|
16
|
+
import ObjectID from "../../Types/ObjectID";
|
|
17
|
+
import Email from "../../Types/Email";
|
|
18
|
+
import Phone from "../../Types/Phone";
|
|
19
|
+
import Domain from "../../Types/Domain";
|
|
20
|
+
import Version from "../../Types/Version";
|
|
21
|
+
import Name from "../../Types/Name";
|
|
22
|
+
import IP from "../../Types/IP/IP";
|
|
23
|
+
import Port from "../../Types/Port";
|
|
24
|
+
import MonitorSteps from "../../Types/Monitor/MonitorSteps";
|
|
16
25
|
|
|
17
26
|
export type ModelSchemaType = ZodSchema;
|
|
18
27
|
|
|
19
|
-
// Type for schema examples
|
|
20
|
-
type SchemaExample = Record<string, unknown>;
|
|
21
|
-
|
|
22
|
-
// Type for operator examples in OpenAPI format
|
|
23
|
-
type OperatorExample = {
|
|
24
|
-
properties: Record<
|
|
25
|
-
string,
|
|
26
|
-
{
|
|
27
|
-
type: string;
|
|
28
|
-
enum?: string[];
|
|
29
|
-
items?: { type: string };
|
|
30
|
-
}
|
|
31
|
-
>;
|
|
32
|
-
required: string[];
|
|
33
|
-
example: Record<string, unknown>;
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
// Type for shape objects using Zod's type inference
|
|
37
|
-
type ShapeRecord = Record<string, ZodTypes.ZodTypeAny>;
|
|
38
|
-
|
|
39
28
|
// Type for schema method functions
|
|
40
29
|
type SchemaMethodFunction = (data: {
|
|
41
30
|
modelType: new () => DatabaseBaseModel;
|
|
42
31
|
}) => ModelSchemaType;
|
|
43
32
|
|
|
44
|
-
export class ModelSchema {
|
|
33
|
+
export class ModelSchema extends BaseSchema {
|
|
45
34
|
/**
|
|
46
35
|
* Format permissions array into a human-readable string for OpenAPI documentation
|
|
47
36
|
*/
|
|
@@ -49,7 +38,7 @@ export class ModelSchema {
|
|
|
49
38
|
permissions: Array<Permission> | undefined,
|
|
50
39
|
): string {
|
|
51
40
|
if (!permissions || permissions.length === 0) {
|
|
52
|
-
return "No
|
|
41
|
+
return "No access - you don't have permission for this operation";
|
|
53
42
|
}
|
|
54
43
|
|
|
55
44
|
return PermissionHelper.getPermissionTitles(permissions).join(", ");
|
|
@@ -92,20 +81,37 @@ export class ModelSchema {
|
|
|
92
81
|
|
|
93
82
|
const shape: ShapeRecord = {};
|
|
94
83
|
|
|
84
|
+
// Get column access control for permission filtering
|
|
85
|
+
const columnAccessControl: Dictionary<ColumnAccessControl> =
|
|
86
|
+
model.getColumnAccessControlForAllColumns();
|
|
87
|
+
|
|
95
88
|
for (const key in columns) {
|
|
96
89
|
const column: TableColumnMetadata | undefined = columns[key];
|
|
97
90
|
if (!column) {
|
|
98
91
|
continue;
|
|
99
92
|
}
|
|
93
|
+
|
|
94
|
+
// Filter out columns with no permissions (root-only access)
|
|
95
|
+
const accessControl: ColumnAccessControl | undefined =
|
|
96
|
+
columnAccessControl[key];
|
|
97
|
+
if (accessControl) {
|
|
98
|
+
// Check if column has any permissions defined for read operation (general schema assumes read access)
|
|
99
|
+
const hasReadPermissions: boolean =
|
|
100
|
+
accessControl.read && accessControl.read.length > 0;
|
|
101
|
+
|
|
102
|
+
// If no read permissions are defined, exclude the column from general schema
|
|
103
|
+
if (!hasReadPermissions) {
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
100
107
|
let zodType: ZodTypes.ZodTypeAny;
|
|
101
108
|
|
|
102
109
|
if (column.type === TableColumnType.ObjectID) {
|
|
103
|
-
zodType =
|
|
104
|
-
type: "string",
|
|
105
|
-
example: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
|
|
106
|
-
});
|
|
110
|
+
zodType = ObjectID.getSchema();
|
|
107
111
|
} else if (column.type === TableColumnType.Color) {
|
|
108
112
|
zodType = Color.getSchema();
|
|
113
|
+
} else if (column.type === TableColumnType.MonitorSteps) {
|
|
114
|
+
zodType = MonitorSteps.getSchema();
|
|
109
115
|
} else if (column.type === TableColumnType.Date) {
|
|
110
116
|
zodType = z.date().openapi({
|
|
111
117
|
type: "string",
|
|
@@ -124,11 +130,7 @@ export class ModelSchema {
|
|
|
124
130
|
) {
|
|
125
131
|
zodType = z.number().openapi({ type: "number", example: 42 });
|
|
126
132
|
} else if (column.type === TableColumnType.Email) {
|
|
127
|
-
zodType =
|
|
128
|
-
type: "string",
|
|
129
|
-
format: "email",
|
|
130
|
-
example: "user@example.com",
|
|
131
|
-
});
|
|
133
|
+
zodType = Email.getSchema();
|
|
132
134
|
} else if (column.type === TableColumnType.HashedString) {
|
|
133
135
|
zodType = z
|
|
134
136
|
.string()
|
|
@@ -148,14 +150,9 @@ export class ModelSchema {
|
|
|
148
150
|
"This is an example of longer text content that might be stored in this field.",
|
|
149
151
|
});
|
|
150
152
|
} else if (column.type === TableColumnType.Phone) {
|
|
151
|
-
zodType =
|
|
152
|
-
.string()
|
|
153
|
-
.openapi({ type: "string", example: "+1-555-123-4567" });
|
|
153
|
+
zodType = Phone.getSchema();
|
|
154
154
|
} else if (column.type === TableColumnType.Version) {
|
|
155
|
-
zodType =
|
|
156
|
-
type: "string",
|
|
157
|
-
example: "1.0.0",
|
|
158
|
-
});
|
|
155
|
+
zodType = Version.getSchema();
|
|
159
156
|
} else if (column.type === TableColumnType.Password) {
|
|
160
157
|
zodType = z.string().openapi({
|
|
161
158
|
type: "string",
|
|
@@ -163,10 +160,7 @@ export class ModelSchema {
|
|
|
163
160
|
example: "••••••••",
|
|
164
161
|
});
|
|
165
162
|
} else if (column.type === TableColumnType.Name) {
|
|
166
|
-
zodType =
|
|
167
|
-
type: "string",
|
|
168
|
-
example: "John Doe",
|
|
169
|
-
});
|
|
163
|
+
zodType = Name.getSchema();
|
|
170
164
|
} else if (column.type === TableColumnType.Description) {
|
|
171
165
|
zodType = z.string().openapi({
|
|
172
166
|
type: "string",
|
|
@@ -193,10 +187,11 @@ export class ModelSchema {
|
|
|
193
187
|
example: "# Heading\n\nThis is **markdown** content",
|
|
194
188
|
});
|
|
195
189
|
} else if (column.type === TableColumnType.Domain) {
|
|
196
|
-
zodType =
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
190
|
+
zodType = Domain.getSchema();
|
|
191
|
+
} else if (column.type === TableColumnType.Port) {
|
|
192
|
+
zodType = Port.getSchema();
|
|
193
|
+
} else if (column.type === TableColumnType.IP) {
|
|
194
|
+
zodType = IP.getSchema();
|
|
200
195
|
} else if (column.type === TableColumnType.LongURL) {
|
|
201
196
|
zodType = z.string().url().openapi({
|
|
202
197
|
type: "string",
|
|
@@ -380,72 +375,36 @@ export class ModelSchema {
|
|
|
380
375
|
const modelType: new () => DatabaseBaseModel = data.modelType;
|
|
381
376
|
const model: DatabaseBaseModel = new modelType();
|
|
382
377
|
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
(operatorType
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
} else if (operatorSchemas.length > 1) {
|
|
413
|
-
columnSchema = z
|
|
414
|
-
.union(
|
|
415
|
-
operatorSchemas as [
|
|
416
|
-
ZodTypes.ZodTypeAny,
|
|
417
|
-
ZodTypes.ZodTypeAny,
|
|
418
|
-
...ZodTypes.ZodTypeAny[],
|
|
419
|
-
],
|
|
420
|
-
)
|
|
421
|
-
.optional();
|
|
422
|
-
} else {
|
|
423
|
-
// Fallback for empty operators array
|
|
424
|
-
columnSchema = z.any().optional();
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
// Add OpenAPI documentation for query operators
|
|
428
|
-
const operatorExamples: Array<OperatorExample> =
|
|
429
|
-
this.getQueryOperatorExamples(column.type, validOperators);
|
|
430
|
-
columnSchema = columnSchema.openapi({
|
|
431
|
-
type: "object",
|
|
432
|
-
description: `Query operators for ${key} field of type ${column.type}. Supported operators: ${validOperators.join(", ")}`,
|
|
433
|
-
example:
|
|
434
|
-
operatorExamples.length > 0 && operatorExamples[0]
|
|
435
|
-
? operatorExamples[0].example
|
|
436
|
-
: {},
|
|
437
|
-
});
|
|
438
|
-
|
|
439
|
-
shape[key] = columnSchema;
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
const schema: ModelSchemaType = z.object(shape).openapi({
|
|
443
|
-
type: "object",
|
|
444
|
-
description: `Query schema for ${model.tableName || "model"} model. Each field can use various operators based on its data type.`,
|
|
445
|
-
example: this.getQuerySchemaExample(modelType),
|
|
378
|
+
return this.generateQuerySchema({
|
|
379
|
+
model,
|
|
380
|
+
tableName: model.tableName || "model",
|
|
381
|
+
getColumns: (model: DatabaseBaseModel) => {
|
|
382
|
+
const columns: Dictionary<TableColumnMetadata> = getTableColumns(model);
|
|
383
|
+
return Object.keys(columns)
|
|
384
|
+
.map((key: string) => {
|
|
385
|
+
const column: TableColumnMetadata | undefined = columns[key];
|
|
386
|
+
return column ? { key, type: column.type } : null;
|
|
387
|
+
})
|
|
388
|
+
.filter((col: { key: string; type: any } | null) => {
|
|
389
|
+
return col !== null;
|
|
390
|
+
}) as Array<{ key: string; type: any }>;
|
|
391
|
+
},
|
|
392
|
+
getValidOperatorsForColumnType: (columnType: TableColumnType) => {
|
|
393
|
+
return this.getValidOperatorsForColumnType(columnType);
|
|
394
|
+
},
|
|
395
|
+
getOperatorSchema: (
|
|
396
|
+
operatorType: string,
|
|
397
|
+
columnType: TableColumnType,
|
|
398
|
+
) => {
|
|
399
|
+
return this.getOperatorSchema(operatorType, columnType);
|
|
400
|
+
},
|
|
401
|
+
getQuerySchemaExample: () => {
|
|
402
|
+
return this.getQuerySchemaExample(modelType);
|
|
403
|
+
},
|
|
404
|
+
getExampleValueForColumn: (columnType: TableColumnType) => {
|
|
405
|
+
return this.getExampleValueForColumn(columnType);
|
|
406
|
+
},
|
|
446
407
|
});
|
|
447
|
-
|
|
448
|
-
return schema;
|
|
449
408
|
}
|
|
450
409
|
|
|
451
410
|
private static getValidOperatorsForColumnType(
|
|
@@ -585,20 +544,34 @@ export class ModelSchema {
|
|
|
585
544
|
): ZodTypes.ZodTypeAny {
|
|
586
545
|
switch (columnType) {
|
|
587
546
|
case TableColumnType.ObjectID:
|
|
588
|
-
return
|
|
547
|
+
return ObjectID.getSchema();
|
|
589
548
|
|
|
590
549
|
case TableColumnType.Email:
|
|
591
|
-
return
|
|
550
|
+
return Email.getSchema();
|
|
592
551
|
|
|
593
552
|
case TableColumnType.Phone:
|
|
553
|
+
return Phone.getSchema();
|
|
554
|
+
|
|
555
|
+
case TableColumnType.Name:
|
|
556
|
+
return Name.getSchema();
|
|
557
|
+
|
|
558
|
+
case TableColumnType.Domain:
|
|
559
|
+
return Domain.getSchema();
|
|
560
|
+
|
|
561
|
+
case TableColumnType.Version:
|
|
562
|
+
return Version.getSchema();
|
|
563
|
+
|
|
564
|
+
case TableColumnType.IP:
|
|
565
|
+
return IP.getSchema();
|
|
566
|
+
case TableColumnType.Port:
|
|
567
|
+
return Port.getSchema();
|
|
568
|
+
|
|
594
569
|
case TableColumnType.HashedString:
|
|
595
570
|
case TableColumnType.Slug:
|
|
596
571
|
case TableColumnType.ShortText:
|
|
597
572
|
case TableColumnType.LongText:
|
|
598
573
|
case TableColumnType.VeryLongText:
|
|
599
|
-
case TableColumnType.Name:
|
|
600
574
|
case TableColumnType.Description:
|
|
601
|
-
case TableColumnType.Domain:
|
|
602
575
|
case TableColumnType.Markdown:
|
|
603
576
|
case TableColumnType.HTML:
|
|
604
577
|
case TableColumnType.JavaScript:
|
|
@@ -607,7 +580,6 @@ export class ModelSchema {
|
|
|
607
580
|
case TableColumnType.ShortURL:
|
|
608
581
|
case TableColumnType.OTP:
|
|
609
582
|
case TableColumnType.Password:
|
|
610
|
-
case TableColumnType.Version:
|
|
611
583
|
return z.string();
|
|
612
584
|
|
|
613
585
|
case TableColumnType.Number:
|
|
@@ -658,40 +630,23 @@ export class ModelSchema {
|
|
|
658
630
|
const modelType: new () => DatabaseBaseModel = data.modelType;
|
|
659
631
|
const model: DatabaseBaseModel = new modelType();
|
|
660
632
|
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
}
|
|
678
|
-
|
|
679
|
-
shape[key] = z
|
|
680
|
-
.enum([SortOrder.Ascending, SortOrder.Descending])
|
|
681
|
-
.optional()
|
|
682
|
-
.openapi({
|
|
683
|
-
type: "string",
|
|
684
|
-
enum: [SortOrder.Ascending, SortOrder.Descending],
|
|
685
|
-
description: `Sort order for ${key} field`,
|
|
686
|
-
example: SortOrder.Ascending,
|
|
687
|
-
});
|
|
688
|
-
}
|
|
689
|
-
|
|
690
|
-
return z.object(shape).openapi({
|
|
691
|
-
type: "object",
|
|
692
|
-
description: `Sort schema for ${model.tableName || "model"} model. Only sortable fields are included.`,
|
|
693
|
-
example: this.getSortSchemaExample(),
|
|
694
|
-
additionalProperties: false,
|
|
633
|
+
return this.generateSortSchema({
|
|
634
|
+
model,
|
|
635
|
+
tableName: model.tableName || "model",
|
|
636
|
+
getSortableTypes: () => {
|
|
637
|
+
return this.getSortableTypes();
|
|
638
|
+
},
|
|
639
|
+
getColumnsForSorting: (model: DatabaseBaseModel) => {
|
|
640
|
+
const columns: Dictionary<TableColumnMetadata> = getTableColumns(model);
|
|
641
|
+
return Object.keys(columns)
|
|
642
|
+
.map((key: string) => {
|
|
643
|
+
const column: TableColumnMetadata | undefined = columns[key];
|
|
644
|
+
return column ? { key, type: column.type } : null;
|
|
645
|
+
})
|
|
646
|
+
.filter((col: { key: string; type: any } | null) => {
|
|
647
|
+
return col !== null;
|
|
648
|
+
}) as Array<{ key: string; type: any }>;
|
|
649
|
+
},
|
|
695
650
|
});
|
|
696
651
|
}
|
|
697
652
|
|
|
@@ -702,50 +657,40 @@ export class ModelSchema {
|
|
|
702
657
|
const modelType: new () => DatabaseBaseModel = data.modelType;
|
|
703
658
|
const model: DatabaseBaseModel = new modelType();
|
|
704
659
|
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
description: `Select ${key} field in the response`,
|
|
740
|
-
example: true,
|
|
741
|
-
});
|
|
742
|
-
}
|
|
743
|
-
|
|
744
|
-
return z.object(shape).openapi({
|
|
745
|
-
type: "object",
|
|
746
|
-
description: `Select schema for ${model.tableName || "model"} model. Set fields to true to include them in the response.`,
|
|
747
|
-
example: this.getSelectSchemaExample(modelType),
|
|
748
|
-
additionalProperties: false,
|
|
660
|
+
return this.generateSelectSchema({
|
|
661
|
+
model,
|
|
662
|
+
tableName: model.tableName || "model",
|
|
663
|
+
getColumns: (model: DatabaseBaseModel) => {
|
|
664
|
+
const columns: Dictionary<TableColumnMetadata> = getTableColumns(model);
|
|
665
|
+
return Object.keys(columns)
|
|
666
|
+
.map((key: string) => {
|
|
667
|
+
const column: TableColumnMetadata | undefined = columns[key];
|
|
668
|
+
return column ? { key, type: column.type } : null;
|
|
669
|
+
})
|
|
670
|
+
.filter((col: { key: string; type: any } | null) => {
|
|
671
|
+
return col !== null;
|
|
672
|
+
}) as Array<{ key: string; type?: any }>;
|
|
673
|
+
},
|
|
674
|
+
getSelectSchemaExample: () => {
|
|
675
|
+
return this.getSelectSchemaExample(modelType);
|
|
676
|
+
},
|
|
677
|
+
allowNested: !data.isNested,
|
|
678
|
+
getNestedSchema: (key: string, model: DatabaseBaseModel) => {
|
|
679
|
+
const columns: Dictionary<TableColumnMetadata> = getTableColumns(model);
|
|
680
|
+
const column: TableColumnMetadata | undefined = columns[key];
|
|
681
|
+
if (
|
|
682
|
+
column &&
|
|
683
|
+
column.modelType &&
|
|
684
|
+
(column.type === TableColumnType.EntityArray ||
|
|
685
|
+
column.type === TableColumnType.Entity)
|
|
686
|
+
) {
|
|
687
|
+
return this.getSelectModelSchema({
|
|
688
|
+
modelType: column.modelType as new () => DatabaseBaseModel,
|
|
689
|
+
isNested: true,
|
|
690
|
+
});
|
|
691
|
+
}
|
|
692
|
+
return null;
|
|
693
|
+
},
|
|
749
694
|
});
|
|
750
695
|
}
|
|
751
696
|
|
|
@@ -755,244 +700,44 @@ export class ModelSchema {
|
|
|
755
700
|
const modelType: new () => DatabaseBaseModel = data.modelType;
|
|
756
701
|
const model: DatabaseBaseModel = new modelType();
|
|
757
702
|
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
.
|
|
792
|
-
|
|
793
|
-
.openapi({
|
|
794
|
-
type: "boolean",
|
|
795
|
-
description: `Group by ${key} field. Only one field can be selected for grouping.`,
|
|
796
|
-
example: true,
|
|
797
|
-
});
|
|
798
|
-
}
|
|
799
|
-
|
|
800
|
-
return z.object(shape).openapi({
|
|
801
|
-
type: "object",
|
|
802
|
-
description: `Group by schema for ${model.tableName || "model"} model. Only one field can be set to true for grouping.`,
|
|
803
|
-
example: this.getGroupBySchemaExample(modelType),
|
|
804
|
-
additionalProperties: false,
|
|
703
|
+
return this.generateGroupBySchema({
|
|
704
|
+
model,
|
|
705
|
+
tableName: model.tableName || "model",
|
|
706
|
+
getColumns: (model: DatabaseBaseModel) => {
|
|
707
|
+
const columns: Dictionary<TableColumnMetadata> = getTableColumns(model);
|
|
708
|
+
return Object.keys(columns)
|
|
709
|
+
.map((key: string) => {
|
|
710
|
+
const column: TableColumnMetadata | undefined = columns[key];
|
|
711
|
+
return column ? { key, type: column.type } : null;
|
|
712
|
+
})
|
|
713
|
+
.filter((col: { key: string; type: any } | null) => {
|
|
714
|
+
return col !== null;
|
|
715
|
+
}) as Array<{ key: string; type: any }>;
|
|
716
|
+
},
|
|
717
|
+
getGroupableTypes: () => {
|
|
718
|
+
return [
|
|
719
|
+
TableColumnType.ShortText,
|
|
720
|
+
TableColumnType.LongText,
|
|
721
|
+
TableColumnType.Name,
|
|
722
|
+
TableColumnType.Email,
|
|
723
|
+
TableColumnType.Slug,
|
|
724
|
+
TableColumnType.ObjectID,
|
|
725
|
+
TableColumnType.Boolean,
|
|
726
|
+
TableColumnType.Date,
|
|
727
|
+
TableColumnType.Number,
|
|
728
|
+
TableColumnType.PositiveNumber,
|
|
729
|
+
TableColumnType.SmallNumber,
|
|
730
|
+
TableColumnType.SmallPositiveNumber,
|
|
731
|
+
TableColumnType.BigNumber,
|
|
732
|
+
TableColumnType.BigPositiveNumber,
|
|
733
|
+
];
|
|
734
|
+
},
|
|
735
|
+
getGroupBySchemaExample: () => {
|
|
736
|
+
return this.getGroupBySchemaExample(modelType);
|
|
737
|
+
},
|
|
805
738
|
});
|
|
806
739
|
}
|
|
807
740
|
|
|
808
|
-
private static getQueryOperatorExamples(
|
|
809
|
-
columnType: TableColumnType,
|
|
810
|
-
validOperators: Array<string>,
|
|
811
|
-
): Array<OperatorExample> {
|
|
812
|
-
const examples: Array<OperatorExample> = [];
|
|
813
|
-
|
|
814
|
-
for (const operator of validOperators) {
|
|
815
|
-
switch (operator) {
|
|
816
|
-
case "EqualTo":
|
|
817
|
-
examples.push({
|
|
818
|
-
properties: {
|
|
819
|
-
_type: { type: "string", enum: ["EqualTo"] },
|
|
820
|
-
value: { type: this.getOpenAPITypeForColumn(columnType) },
|
|
821
|
-
},
|
|
822
|
-
required: ["_type", "value"],
|
|
823
|
-
example: {
|
|
824
|
-
_type: "EqualTo",
|
|
825
|
-
value: this.getExampleValueForColumn(columnType),
|
|
826
|
-
},
|
|
827
|
-
});
|
|
828
|
-
break;
|
|
829
|
-
case "NotEqual":
|
|
830
|
-
examples.push({
|
|
831
|
-
properties: {
|
|
832
|
-
_type: { type: "string", enum: ["NotEqual"] },
|
|
833
|
-
value: { type: this.getOpenAPITypeForColumn(columnType) },
|
|
834
|
-
},
|
|
835
|
-
required: ["_type", "value"],
|
|
836
|
-
example: {
|
|
837
|
-
_type: "NotEqual",
|
|
838
|
-
value: this.getExampleValueForColumn(columnType),
|
|
839
|
-
},
|
|
840
|
-
});
|
|
841
|
-
break;
|
|
842
|
-
case "Search":
|
|
843
|
-
examples.push({
|
|
844
|
-
properties: {
|
|
845
|
-
_type: { type: "string", enum: ["Search"] },
|
|
846
|
-
value: { type: "string" },
|
|
847
|
-
},
|
|
848
|
-
required: ["_type", "value"],
|
|
849
|
-
example: { _type: "Search", value: "search term" },
|
|
850
|
-
});
|
|
851
|
-
break;
|
|
852
|
-
case "GreaterThan":
|
|
853
|
-
examples.push({
|
|
854
|
-
properties: {
|
|
855
|
-
_type: { type: "string", enum: ["GreaterThan"] },
|
|
856
|
-
value: { type: this.getOpenAPITypeForColumn(columnType) },
|
|
857
|
-
},
|
|
858
|
-
required: ["_type", "value"],
|
|
859
|
-
example: {
|
|
860
|
-
_type: "GreaterThan",
|
|
861
|
-
value: this.getExampleValueForColumn(columnType),
|
|
862
|
-
},
|
|
863
|
-
});
|
|
864
|
-
break;
|
|
865
|
-
case "LessThan":
|
|
866
|
-
examples.push({
|
|
867
|
-
properties: {
|
|
868
|
-
_type: { type: "string", enum: ["LessThan"] },
|
|
869
|
-
value: { type: this.getOpenAPITypeForColumn(columnType) },
|
|
870
|
-
},
|
|
871
|
-
required: ["_type", "value"],
|
|
872
|
-
example: {
|
|
873
|
-
_type: "LessThan",
|
|
874
|
-
value: this.getExampleValueForColumn(columnType),
|
|
875
|
-
},
|
|
876
|
-
});
|
|
877
|
-
break;
|
|
878
|
-
case "GreaterThanOrEqual":
|
|
879
|
-
examples.push({
|
|
880
|
-
properties: {
|
|
881
|
-
_type: { type: "string", enum: ["GreaterThanOrEqual"] },
|
|
882
|
-
value: { type: this.getOpenAPITypeForColumn(columnType) },
|
|
883
|
-
},
|
|
884
|
-
required: ["_type", "value"],
|
|
885
|
-
example: {
|
|
886
|
-
_type: "GreaterThanOrEqual",
|
|
887
|
-
value: this.getExampleValueForColumn(columnType),
|
|
888
|
-
},
|
|
889
|
-
});
|
|
890
|
-
break;
|
|
891
|
-
case "LessThanOrEqual":
|
|
892
|
-
examples.push({
|
|
893
|
-
properties: {
|
|
894
|
-
_type: { type: "string", enum: ["LessThanOrEqual"] },
|
|
895
|
-
value: { type: this.getOpenAPITypeForColumn(columnType) },
|
|
896
|
-
},
|
|
897
|
-
required: ["_type", "value"],
|
|
898
|
-
example: {
|
|
899
|
-
_type: "LessThanOrEqual",
|
|
900
|
-
value: this.getExampleValueForColumn(columnType),
|
|
901
|
-
},
|
|
902
|
-
});
|
|
903
|
-
break;
|
|
904
|
-
case "EqualToOrNull":
|
|
905
|
-
examples.push({
|
|
906
|
-
properties: {
|
|
907
|
-
_type: { type: "string", enum: ["EqualToOrNull"] },
|
|
908
|
-
value: { type: this.getOpenAPITypeForColumn(columnType) },
|
|
909
|
-
},
|
|
910
|
-
required: ["_type", "value"],
|
|
911
|
-
example: {
|
|
912
|
-
_type: "EqualToOrNull",
|
|
913
|
-
value: this.getExampleValueForColumn(columnType),
|
|
914
|
-
},
|
|
915
|
-
});
|
|
916
|
-
break;
|
|
917
|
-
case "InBetween":
|
|
918
|
-
examples.push({
|
|
919
|
-
properties: {
|
|
920
|
-
_type: { type: "string", enum: ["InBetween"] },
|
|
921
|
-
startValue: { type: this.getOpenAPITypeForColumn(columnType) },
|
|
922
|
-
endValue: { type: this.getOpenAPITypeForColumn(columnType) },
|
|
923
|
-
},
|
|
924
|
-
required: ["_type", "startValue", "endValue"],
|
|
925
|
-
example: {
|
|
926
|
-
_type: "InBetween",
|
|
927
|
-
startValue: this.getExampleValueForColumn(columnType),
|
|
928
|
-
endValue: this.getExampleValueForColumn(columnType, true),
|
|
929
|
-
},
|
|
930
|
-
});
|
|
931
|
-
break;
|
|
932
|
-
case "IsNull":
|
|
933
|
-
examples.push({
|
|
934
|
-
properties: {
|
|
935
|
-
_type: { type: "string", enum: ["IsNull"] },
|
|
936
|
-
},
|
|
937
|
-
required: ["_type"],
|
|
938
|
-
example: { _type: "IsNull" },
|
|
939
|
-
});
|
|
940
|
-
break;
|
|
941
|
-
case "NotNull":
|
|
942
|
-
examples.push({
|
|
943
|
-
properties: {
|
|
944
|
-
_type: { type: "string", enum: ["NotNull"] },
|
|
945
|
-
},
|
|
946
|
-
required: ["_type"],
|
|
947
|
-
example: { _type: "NotNull" },
|
|
948
|
-
});
|
|
949
|
-
break;
|
|
950
|
-
case "Includes":
|
|
951
|
-
examples.push({
|
|
952
|
-
properties: {
|
|
953
|
-
_type: { type: "string", enum: ["Includes"] },
|
|
954
|
-
value: {
|
|
955
|
-
type: "array",
|
|
956
|
-
items: { type: this.getOpenAPITypeForColumn(columnType) },
|
|
957
|
-
},
|
|
958
|
-
},
|
|
959
|
-
required: ["_type", "value"],
|
|
960
|
-
example: {
|
|
961
|
-
_type: "Includes",
|
|
962
|
-
value: [
|
|
963
|
-
this.getExampleValueForColumn(columnType),
|
|
964
|
-
this.getExampleValueForColumn(columnType, true),
|
|
965
|
-
],
|
|
966
|
-
},
|
|
967
|
-
});
|
|
968
|
-
break;
|
|
969
|
-
}
|
|
970
|
-
}
|
|
971
|
-
|
|
972
|
-
return examples;
|
|
973
|
-
}
|
|
974
|
-
|
|
975
|
-
private static getOpenAPITypeForColumn(columnType: TableColumnType): string {
|
|
976
|
-
switch (columnType) {
|
|
977
|
-
case TableColumnType.Number:
|
|
978
|
-
case TableColumnType.PositiveNumber:
|
|
979
|
-
case TableColumnType.SmallNumber:
|
|
980
|
-
case TableColumnType.SmallPositiveNumber:
|
|
981
|
-
case TableColumnType.BigNumber:
|
|
982
|
-
case TableColumnType.BigPositiveNumber:
|
|
983
|
-
return "number";
|
|
984
|
-
case TableColumnType.Boolean:
|
|
985
|
-
return "boolean";
|
|
986
|
-
case TableColumnType.Date:
|
|
987
|
-
return "string";
|
|
988
|
-
case TableColumnType.JSON:
|
|
989
|
-
case TableColumnType.Array:
|
|
990
|
-
return "object";
|
|
991
|
-
default:
|
|
992
|
-
return "string";
|
|
993
|
-
}
|
|
994
|
-
}
|
|
995
|
-
|
|
996
741
|
private static getExampleValueForColumn(
|
|
997
742
|
columnType: TableColumnType,
|
|
998
743
|
isSecondValue: boolean = false,
|
|
@@ -1124,12 +869,6 @@ export class ModelSchema {
|
|
|
1124
869
|
return example;
|
|
1125
870
|
}
|
|
1126
871
|
|
|
1127
|
-
private static getSortSchemaExample(): SchemaExample {
|
|
1128
|
-
return {
|
|
1129
|
-
createdAt: "Descending",
|
|
1130
|
-
};
|
|
1131
|
-
}
|
|
1132
|
-
|
|
1133
872
|
private static getSelectSchemaExample(
|
|
1134
873
|
modelType: new () => DatabaseBaseModel,
|
|
1135
874
|
): SchemaExample {
|
|
@@ -1257,6 +996,10 @@ export class ModelSchema {
|
|
|
1257
996
|
const columns: Dictionary<TableColumnMetadata> = getTableColumns(model);
|
|
1258
997
|
const shape: ShapeRecord = {};
|
|
1259
998
|
|
|
999
|
+
// Get column access control for permission filtering
|
|
1000
|
+
const columnAccessControl: Dictionary<ColumnAccessControl> =
|
|
1001
|
+
model.getColumnAccessControlForAllColumns();
|
|
1002
|
+
|
|
1260
1003
|
for (const key in columns) {
|
|
1261
1004
|
const column: TableColumnMetadata | undefined = columns[key];
|
|
1262
1005
|
if (!column) {
|
|
@@ -1273,6 +1016,42 @@ export class ModelSchema {
|
|
|
1273
1016
|
continue;
|
|
1274
1017
|
}
|
|
1275
1018
|
|
|
1019
|
+
// Filter out columns with no permissions (root-only access)
|
|
1020
|
+
const accessControl: ColumnAccessControl | undefined =
|
|
1021
|
+
columnAccessControl[key];
|
|
1022
|
+
if (accessControl) {
|
|
1023
|
+
let hasPermissions: boolean = false;
|
|
1024
|
+
|
|
1025
|
+
// Check if column has any permissions defined for the current operation
|
|
1026
|
+
if (
|
|
1027
|
+
data.schemaType === "create" &&
|
|
1028
|
+
accessControl.create &&
|
|
1029
|
+
accessControl.create.length > 0
|
|
1030
|
+
) {
|
|
1031
|
+
hasPermissions = true;
|
|
1032
|
+
} else if (
|
|
1033
|
+
data.schemaType === "read" &&
|
|
1034
|
+
accessControl.read &&
|
|
1035
|
+
accessControl.read.length > 0
|
|
1036
|
+
) {
|
|
1037
|
+
hasPermissions = true;
|
|
1038
|
+
} else if (
|
|
1039
|
+
data.schemaType === "update" &&
|
|
1040
|
+
accessControl.update &&
|
|
1041
|
+
accessControl.update.length > 0
|
|
1042
|
+
) {
|
|
1043
|
+
hasPermissions = true;
|
|
1044
|
+
} else if (data.schemaType === "delete") {
|
|
1045
|
+
// For delete operations, we don't filter by column permissions
|
|
1046
|
+
hasPermissions = true;
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1049
|
+
// If no permissions are defined for this operation, exclude the column
|
|
1050
|
+
if (!hasPermissions) {
|
|
1051
|
+
continue;
|
|
1052
|
+
}
|
|
1053
|
+
}
|
|
1054
|
+
|
|
1276
1055
|
let zodType: ZodTypes.ZodTypeAny = this.getZodTypeForColumn(
|
|
1277
1056
|
column,
|
|
1278
1057
|
key,
|
|
@@ -1319,10 +1098,13 @@ export class ModelSchema {
|
|
|
1319
1098
|
let zodType: ZodTypes.ZodTypeAny;
|
|
1320
1099
|
|
|
1321
1100
|
if (column.type === TableColumnType.ObjectID) {
|
|
1322
|
-
zodType =
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1101
|
+
zodType = ObjectID.getSchema();
|
|
1102
|
+
} else if (column.type === TableColumnType.Port) {
|
|
1103
|
+
zodType = Port.getSchema();
|
|
1104
|
+
} else if (column.type === TableColumnType.MonitorSteps) {
|
|
1105
|
+
zodType = MonitorSteps.getSchema();
|
|
1106
|
+
} else if (column.type === TableColumnType.IP) {
|
|
1107
|
+
zodType = IP.getSchema();
|
|
1326
1108
|
} else if (column.type === TableColumnType.Color) {
|
|
1327
1109
|
zodType = Color.getSchema();
|
|
1328
1110
|
} else if (column.type === TableColumnType.Date) {
|
|
@@ -1343,11 +1125,7 @@ export class ModelSchema {
|
|
|
1343
1125
|
) {
|
|
1344
1126
|
zodType = z.number().openapi({ type: "number", example: 42 });
|
|
1345
1127
|
} else if (column.type === TableColumnType.Email) {
|
|
1346
|
-
zodType =
|
|
1347
|
-
type: "string",
|
|
1348
|
-
format: "email",
|
|
1349
|
-
example: "user@example.com",
|
|
1350
|
-
});
|
|
1128
|
+
zodType = Email.getSchema();
|
|
1351
1129
|
} else if (column.type === TableColumnType.HashedString) {
|
|
1352
1130
|
zodType = z
|
|
1353
1131
|
.string()
|
|
@@ -1367,14 +1145,9 @@ export class ModelSchema {
|
|
|
1367
1145
|
"This is an example of longer text content that might be stored in this field.",
|
|
1368
1146
|
});
|
|
1369
1147
|
} else if (column.type === TableColumnType.Phone) {
|
|
1370
|
-
zodType =
|
|
1371
|
-
.string()
|
|
1372
|
-
.openapi({ type: "string", example: "+1-555-123-4567" });
|
|
1148
|
+
zodType = Phone.getSchema();
|
|
1373
1149
|
} else if (column.type === TableColumnType.Version) {
|
|
1374
|
-
zodType =
|
|
1375
|
-
type: "string",
|
|
1376
|
-
example: "1.0.0",
|
|
1377
|
-
});
|
|
1150
|
+
zodType = Version.getSchema();
|
|
1378
1151
|
} else if (column.type === TableColumnType.Password) {
|
|
1379
1152
|
zodType = z.string().openapi({
|
|
1380
1153
|
type: "string",
|
|
@@ -1382,10 +1155,7 @@ export class ModelSchema {
|
|
|
1382
1155
|
example: "••••••••",
|
|
1383
1156
|
});
|
|
1384
1157
|
} else if (column.type === TableColumnType.Name) {
|
|
1385
|
-
zodType =
|
|
1386
|
-
type: "string",
|
|
1387
|
-
example: "John Doe",
|
|
1388
|
-
});
|
|
1158
|
+
zodType = Name.getSchema();
|
|
1389
1159
|
} else if (column.type === TableColumnType.Description) {
|
|
1390
1160
|
zodType = z.string().openapi({
|
|
1391
1161
|
type: "string",
|
|
@@ -1412,10 +1182,7 @@ export class ModelSchema {
|
|
|
1412
1182
|
example: "# Heading\n\nThis is **markdown** content",
|
|
1413
1183
|
});
|
|
1414
1184
|
} else if (column.type === TableColumnType.Domain) {
|
|
1415
|
-
zodType =
|
|
1416
|
-
type: "string",
|
|
1417
|
-
example: "example.com",
|
|
1418
|
-
});
|
|
1185
|
+
zodType = Domain.getSchema();
|
|
1419
1186
|
} else if (column.type === TableColumnType.LongURL) {
|
|
1420
1187
|
zodType = z.string().url().openapi({
|
|
1421
1188
|
type: "string",
|